Dans un jeu basé sur des tuiles 2D, quelle est la bonne méthode de défilement?

9

J'utilise Direct3D avec le wrapper D3DXSPRITE pour dessiner les tuiles à l'écran. J'ai une classe de tuiles qui contient des membres tels que la collision et le type de tuile, puis j'ai un tableau de tuiles par exemple

Grille de tuiles [256] [256];

Quelle serait la meilleure méthode?

-Dessinez le joueur au centre de l'écran et décalez où la carte dessine.

-Déplacez le lecteur avec la caméra suivante.

J'utilisais la première méthode, mais cela devient vraiment compliqué lorsque vous arrivez en haut à gauche de la carte, et lorsque d'autres joueurs / ennemis sont sur la carte et se déplacent en même temps

si je fais suivre la caméra au joueur, devrais-je appeler spriteBatch-> Draw (...) pour chaque tuile de la grille même si seulement quelques-unes peuvent tenir sur l'écran?


la source

Réponses:

4

Il est probablement préférable de faire toutes les mises à jour et les calculs en unités "réelles" et mondiales et de déplacer la caméra. Votre spriteBatch peut effectuer lui-même l'abattage mais s'il est trop lent, vous pouvez essayer de déterminer quelles tuiles doivent être affichées à l'écran et ne dessiner que celles-ci.


la source
Vous voudrez probablement écrire du code pour dessiner uniquement les sprites qui sont visibles, surtout si vous trouvez que vous devez augmenter la taille de votre grille.
2

Déplacer la caméra en coordonnées mondiales et faire déplacer votre personnage dans le monde est la façon la plus simple d'aborder ce problème, travailler en coordonnées mondiales signifie que vous n'avez pas besoin de faire de calculs supplémentaires quand cela se résume à tous les autres systèmes qui doivent fonctionner sur un système de coordonnées relatives et également comprendre où ils se trouvent dans les coordonnées du monde.

Puisque vous travaillez en 2D, une autre bonne astuce consiste à faire un partitionnement spatial de la manière la plus simple serait de créer un système de grille de monde virtuel, cela vous permettra de gérer chaque tuile individuellement en associant des sprites et d'autres ressources par tuile, donc en substance, le processus serait:

  • créer une classe de tuile qui peut contenir les coordonnées de limite pour la tuile et toutes les ressources dont une tuile spécifique peut avoir besoin (sprites, ennemis, etc.).

  • décidez de la taille de votre monde et créez un tableau 2D (vous pouvez utiliser une dimension et y accéder en 2D) de tuiles représentant chacune un peu de votre monde avec toutes ses ressources associées.

  • tirez uniquement des ressources de la tuile dans laquelle se trouve le joueur et de ses voisins.

Avec une grille, vous pouvez facilement découvrir dans quelle tuile le joueur se trouve en fonction de sa position par rapport au début de la grille.

Pour contourner le problème que vous avez mentionné à propos de la caméra, vous devez faire du lecteur et de la caméra deux systèmes indépendants où la caméra ne se déplacera pas plus loin que le centre des tuiles de bord. tuile entière car il est lié par les coordonnées du monde (c'est-à-dire qu'il n'est plus centré sur l'écran) mais la caméra est verrouillée.

Sergio Franco
la source
0

J'utilise une surface. Je crée le monde entier sur une surface hors écran et garde une coordonnée x et y. Je les modifie au fur et à mesure que le joueur se déplace et chaque image dessine un rectangle de 1028 x 768 de la surface au backbuffer en utilisant x et y.

quant aux autres personnes je leur donne un x et y et je les laisse se déplacer dans le monde à leur guise, en dessinant je vérifie s'il y a x et y dans le rectangle 1028 x 768 et si oui dessine-les (j'utilise des textures pour les gens) .

J'ai le joueur au centre de l'écran et vérifie si le bord du monde a atteint le bord de l'écran. Dans ce cas, le joueur se déplace sur l'écran jusqu'au bord du monde et revient au centre, puis le monde recommence à bouger. ça me parait difficile et m'a pris du temps mais ce n'est pas trop mal à faire.

J'utilise des tuiles 64 x 64 et le plus grand monde que j'ai utilisé jusqu'à présent est de 50 x 60 tuiles.

Tout cela se fait en direct x avec c ++

Skeith
la source
1
Cela ressemble à un énorme porc de mémoire. Garder le monde entier dessiné dans une surface hors écran vous créera des problèmes de mémoire une fois que vous commencerez à vouloir faire des choses comme avoir plusieurs couches (animées) pour votre monde et l'étendre plus loin que ce que vous avez maintenant. Il serait préférable de conserver les informations sur le monde et de ne dessiner les parties / objets à dessiner que lorsqu'ils doivent l'être. Juste mes 2 cents. :)
Richard Marskell - Drackir
@Drackir Je pense que vous vous méprenez. seul le monde est retiré de l'écran, des choses comme les autres personnes sont suivies et dessinées sur le tampon de backer quand elles sont nécessaires. aussi je ne me vois pas faire plus que 70 x 70 du monde. quand je dis monde, je veux dire zone, cela pourrait être une ville, un donjon ou l'intérieur d'une maison, lorsque le joueur se déplace entre eux, la surface hors écran est reconstruite. Oui, cela prend de la mémoire, mais les tuiles 2D sur les disques modernes en terrabite le rendent négligeable et quelques secondes de chargement sont un petit prix à payer pour un défilement et une animation fluides. mais oui il y a des moyens meilleurs et plus difficiles :)
Skeith
La surface doit être stockée dans la mémoire de la carte GFX, pas sur le disque dur. Cependant, je crois que si la mémoire de la carte GFX est trop grande, elle déplacera les surfaces sur le HD, ce qui ralentirait considérablement les choses. Certes, cela fait un moment que je n'ai pas traité de ces choses, donc je ne me souviens pas exactement comment cela a fonctionné, mais je suppose que tant que vous ne dessinez pas un monde trop grand, ce serait bien. :)
Richard Marskell - Drackir
@Drackir C'est intéressant à savoir, je n'y ai jamais pensé comme ça. J'ai trouvé que cette façon me donne un défilement plus lisse que si je dessinais dynamiquement de nouvelles tuiles, donc je pense que ça va bien mais je devrai y réfléchir.
Skeith
Je travaillais sur un jeu où j'avais des cartes 31x31 mais elles étaient attachées côte à côte. J'essayais de travailler à partir du moteur de quelqu'un d'autre et ils dessinaient toutes les cartes entourant celle sur laquelle se trouvait le joueur; donc neuf cartes au total. Chaque carte avait plusieurs (je pense 6) couches. Donc, comme 31x31x9x6 = 51894 tuiles dessinées (max bien sûr; toutes les tuiles n'étaient pas pleines) à chaque fois que l'utilisateur change de carte. Cela a été un énorme ralentissement pour moi, j'ai donc réécrit la routine de dessin pour ne dessiner que les tuiles entourant le joueur jusqu'à 1 tuile au-delà du bord de l'écran (pour gérer les tuiles partielles pendant le déplacement).
Richard Marskell - Drackir
0

Il est tout à fait normal que le code soit un peu pénible dans les coins d'un monde carrelé, lorsque vous déterminez les éléments à dessiner et assurez-vous simultanément que la caméra ne sort pas du monde. Ces cas de bord sont fondamentalement la chose la plus contraignante à implémenter un monde basé sur des tuiles 2D qui est plus grand que la résolution de l'écran. Cela devient beaucoup plus complexe si vous prenez en charge le zoom avant et le zoom sur le curseur: D

cliffski
la source