2009-11-01 7 views
2

Je suis en train de faire mon moteur 2D pour un jeu Beat'em Up (Castle Crashers est ce que j'appelle Beat'em Up ou Brawler). Je prendra en charge les sprites 2D et les émetteurs de particules 2D. Tout est fait dans le moteur maintenant. Mais je suis venu à une question que je voudrais demander des conseils:Battre em 'up la gestion de l'espace de jeu?

Il est sur la gestion « de l'espace », ce que je pensais faire quelque chose que cette image montre:

alt text http://img337.imageshack.us/img337/9162/spacingprototype1.png

Mon idée est de faire une grille (Spatial Hash ou Grid), du sol où vivront mes émetteurs de particules/sprites 2D. Dans ma photo, j'ai énuméré ces créneaux de 1 à N, (ne doit pas être 35, c'est juste pour montrer des buts). Mon idée est de dessiner les "GameElements" (Sprites/Emetteurs) dans l'ordre de 0 à N, (allant du godet 0 au godet N), alors je vais les faire afficher correctement se chevaucher sur l'écran (retour vers l'avant). Je sais que cela pourrait être fait en comparant simplement l'axe Y inférieur de chaque élément et en effectuant un "quicksort" aussi, mais avoir la grille pourrait me permettre d'effectuer une détection de collision de meilleure façon, et si je fais quelque chose comme A * mettre en place une sorte d'IA, ça pourrait m'aider aussi.

+1

mais les objets du jeu seront-ils alignés sur la grille? Ou ils seront libres de se déplacer n'importe où? – Jack

+3

Quelle est la question? –

+1

@Jackk: Bonjour, non, libre de bouger n'importe où. @Wcoenen: La question est de savoir si cette approche est assez bonne, ou s'il y a une façon plus intelligente/beaucoup plus facile de résoudre mon problème que je ne vois pas. Désolé si je ne l'ai pas fait clair :) – Goles

Répondre

5

Si vous voulez avoir une sorte d'optimisation pour le nombre d'objets dont vous avez besoin pour tester les uns contre les autres, vous voudrez peut-être penser à utiliser un quadtree http://en.wikipedia.org/wiki/Quadtree

L'idée est de diviser l'écran en 4 nœuds, en plaçant tous les éléments dans le nœud auquel ils appartiennent, puis divisez les nœuds que vous venez de créer en 4 autres s'il y a des sprites/items/quoi que ce soit là-dedans qui doivent être testés. Continuez à le faire jusqu'à ce qu'une certaine taille ou quantité d'éléments dans un nœud ait été atteinte.

Vous pouvez ensuite demander au nœud supérieur s'il contient l'élément que vous souhaitez tester. Ce nœud demandera alors aux nœuds enfants s'il contient l'élément, ce qui à son tour demandera à leurs enfants. De cette façon, une grande partie de l'écran peut déjà être ignorée (si elle se trouve dans enfant 00, vous pouvez ignorer les enfants 01, 10 et 11). Ensuite, vous obtenez une liste d'éléments sur lesquels vous effectuez une détection de collision plus spécifique lorsque vous le souhaitez.

Si vous deviez le rendre visuel, il ressemblerait un peu comme ceci:

alt text http://geodata.ethz.ch/geovite/tutorials/L2GeodataStructuresAndDataModels/en/images/quadtree.gif

+0

Bonjour, merci pour la réponse :), vous parlez d'optimisation de la détection de collision correcte? Je pense que cette approche pourrait être très utile pour cela, car d'après ce que je vois, elle pourrait gérer des sprites 2D de taille différente avec moins de problèmes qu'une grille statique. – Goles

+0

En effet, mais comme toujours: jamais prématurément optimiser! Faites fonctionner les choses d'abord, peut-être n'avez-vous même pas besoin d'un tel système, mais c'est à vous de décider. En plus de ce système, vous pouvez également déplacer les grilles de niveau supérieur de sorte que si un article ne rentre pas bien dans une boîte, vous devrez placer une boîte plus haut. Dans le pire des cas, dans un quadtree par défaut, vous devez le déplacer jusqu'à la case la plus haute (pensez à un chevauchement entre les cases 00 et 01). Cela vous oblige à avoir une détection de collision avec cet objet à chaque fois (pas nécessairement mauvais si c'est juste un). –

1

les feu dans la mémoire tampon Z et de laisser cette inquiétude à ce sujet.

Si vous trouvez que dans le futur c'est trop lent (via le profilage évidemment), alors cherchez à l'optimiser.

Prenez la solution la plus simple et passez à autre chose.

1

Votre méthode échoue si vous avez deux sprites occupant la même case dans la grille. Supposons que vous ayez deux ennemis debout dans la même case. L'un se tient légèrement devant l'autre. Lequel dessinez-vous en premier? Vous auriez besoin de deux algorithmes - un qui divise les sprites dans la grille, et le second qui regarde les coordonnées z de tous les sprites dans une boîte de grille donnée et les dessine en fonction de cette valeur.

Une méthode beaucoup plus simple consiste à avoir une seule collection de tous les sprites. Il devrait stocker tous les sprites triés par leurs coordonnées z (de l'arrière de l'écran en tête de la liste à l'avant de l'écran à l'arrière). Parcourez la collection en boucle et dessinez chaque sprite tel qu'il apparaît.Quand un sprite entre ou sort de l'écran (c'est-à-dire ses changements de coordonnées z), vous pouvez effectuer un tri très simple pour déplacer cette seule image-objet dans la collection. Continuez à l'échanger avec l'image-objet suivante dans la liste jusqu'à ce que la coordonnée z de l'image-objet suivante soit supérieure/inférieure à (le cas échéant) la coordonnée de l'image-objet modifiée.

+0

Oui, cela semble beaucoup plus simple, et a beaucoup de sens ... mais que se passe-t-il si la plupart des sprites bougent la plupart du temps? Pensez-vous que ce sera assez efficace? – Goles

+0

Tout ce que vous faites est d'échanger au moins une demi-douzaine de pointeurs autour. Le coût devrait être essentiellement négligeable. – Ant