Question
Lorsque vous avez un jeu 2D qui utilise de très grandes images (plus grandes que ce que votre matériel peut supporter), que faites-vous? Peut-être y a-t-il une solution intéressante à ce problème qui ne m'est jamais venue à l'esprit auparavant.
Je travaille essentiellement sur une sorte de créateur de jeux d'aventure graphique. Mon public cible est constitué de personnes ayant peu ou pas d'expérience en développement (et programmation) de jeux. Si vous travailliez avec une telle application, ne préféreriez-vous pas qu'elle gère le problème en interne plutôt que de vous dire de "partager vos images"?
Le contexte
Il est bien connu que les cartes graphiques imposent un ensemble de restrictions sur la taille des textures qu'elles peuvent utiliser. Par exemple, lorsque vous travaillez avec XNA, vous êtes limité à une taille de texture maximale de 2048 ou 4096 pixels selon le profil que vous choisissez.
Habituellement, cela ne pose pas beaucoup de problèmes dans les jeux 2D car la plupart d'entre eux ont des niveaux qui peuvent être construits à partir de petites pièces individuelles (par exemple des tuiles ou des sprites transformés).
Mais pensez à quelques jeux classiques d'aventure graphique point'n'click (par exemple Monkey Island). Les pièces des jeux d'aventure graphique sont généralement conçues dans leur ensemble, avec peu ou pas de sections reproductibles, tout comme un peintre travaillant sur un paysage. Ou peut-être un jeu comme Final Fantasy 7 qui utilise de grands arrière-plans pré-rendus.
Certaines de ces pièces peuvent devenir assez grandes, s'étendant souvent sur trois écrans de largeur ou plus. Maintenant, si nous considérons ces arrière-plans dans le contexte d'un jeu haute définition moderne, ils dépasseront facilement la taille de texture maximale prise en charge.
Maintenant, la solution évidente à cela est de diviser l'arrière-plan en sections plus petites qui correspondent aux exigences et de les dessiner côte à côte. Mais est-ce que vous (ou votre artiste) devez être celui qui divise toutes vos textures?
Si vous travaillez avec une API de haut niveau, ne devrait-elle pas être prête à faire face à cette situation et à effectuer le fractionnement et l'assemblage des textures en interne (soit en tant que prétraitement tel que Content Pipeline de XNA ou au moment de l'exécution)?
Éditer
Voici ce que je pensais, du point de vue de la mise en œuvre de XNA.
Mon moteur 2D ne nécessite qu'un très petit sous-ensemble des fonctionnalités de Texture2D. Je peux en fait le réduire à cette interface:
public interface ITexture
{
int Height { get; }
int Width { get; }
void Draw(SpriteBatch spriteBatch, Vector2 position, Rectangle? source, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
}
La seule méthode externe que j'utilise qui repose sur Texture2D est SpriteBatch.Draw () afin que je puisse créer un pont entre eux en ajoutant une méthode d'extension:
public static void Draw(this SpriteBatch spriteBatch, ITexture texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
{
texture.Draw(spriteBatch, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth);
}
Cela me permettrait d'utiliser une ITexture de manière interchangeable chaque fois que j'utilisais un Texture2D auparavant.
Ensuite, je pourrais créer deux implémentations différentes d'ITexture, par exemple RegularTexture et LargeTexture, où RegularTexture emballerait simplement un Texture2D normal.
D'un autre côté, LargeTexture conserverait une liste de Texture2D correspondant chacun à l'un des morceaux fractionnés de l'image complète. La partie la plus importante est que l'appel de Draw () sur la LargeTexture devrait être capable d'appliquer toutes les transformations et de dessiner toutes les pièces comme si elles n'étaient qu'une seule image contiguë.
Enfin, pour rendre l'ensemble du processus transparent, je créerais une classe de chargeur de texture unifiée qui agirait comme une méthode d'usine. Il prendrait le chemin de la texture comme paramètre et retournerait une ITexture qui serait soit une RegularTexture soit une LargeTexture selon la taille de l'image dépassant la limite ou non. Mais l'utilisateur n'avait pas besoin de savoir lequel c'était.
Un peu exagéré ou ça sonne bien?