Ok, j'ai donc une grande liste de toutes mes entités que je boucle et mets à jour. Dans AS3, je peux stocker cela comme un tableau (longueur dynamique, non typé), un vecteur (typé) ou une liste chaînée (non native). Pour le moment, j'utilise Array, mais je prévois de passer à Vector ou à une liste liée si elle est plus rapide.
Quoi qu'il en soit, ma question, lorsqu'une entité est détruite, comment dois-je la supprimer de la liste? Je pourrais annuler sa position, l'épisser ou simplement mettre un drapeau dessus pour dire "saute-moi, je suis mort". Je mets mes entités en commun, donc une Entité qui est morte est très susceptible d'être de nouveau vivante à un moment donné. Pour chaque type de collection, quelle est ma meilleure stratégie et quelle combinaison de type de collection et de méthode de suppression fonctionnera le mieux?
Réponses:
Je voudrais stocker tous les ajouts / suppressions dans des listes distinctes et effectuer ces opérations après avoir parcouru la boucle de mise à jour.
la source
Le framework Flixel utilise l'indicateur mort (en fait plusieurs indicateurs qui déterminent s'il doit être dessiné, mis à jour, etc.). Je dirais que si vous allez faire revivre des entités, et si les performances sont un problème, vous utilisez l'indicateur mort. D'après mon expérience, l'instanciation de nouvelles entités est l'opération la plus coûteuse dans le cas d'utilisation que vous décrivez, et l'épissage ou la suppression d'éléments peut entraîner un gonflement de la mémoire compte tenu de la collecte des ordures parfois squirrely de Flash.
la source
dead
aide vraiment à la performance.Bien que certaines techniques soient intrinsèquement plus efficaces que d'autres, cela n'aura d'importance que si vous manquez de cycles sur votre plate-forme cible. Utilisez la technique qui vous permet de terminer votre jeu plus rapidement. Essayez de ne pas compter sur l'implémentation spécifique de vos structures de données de conteneur entre-temps et cela vous aidera à optimiser par la suite si vous en avez besoin.
Juste pour aborder certaines des techniques déjà discutées par d'autres ici. Si l'ordre des entités est important, un indicateur mort peut vous permettre d'épisser pendant votre boucle de mise à jour sur la trame suivante. par exemple. pseudocode très simple:
Ce sont les caractéristiques de ce schéma:
la source
Parlant de mon expérience de programmation générale, l'épissage est généralement une opération lente, impliquant le déplacement de tous les éléments existants vers le haut. Je pense que le mettre à null serait la meilleure solution ici ; un indicateur mort fonctionnerait mais vous devriez faire attention de ne pas le laisser rendre votre code en désordre.
En fait, nous parlions simplement de la mise en commun des ressources dans le salon de discussion. C'est une très bonne pratique, et bon d'entendre que vous faites cela. :)
la source
Personnellement, j'utiliserais une liste chaînée. Il est rapide de parcourir une liste de favoris, ainsi que d'ajouter et de supprimer des éléments. L'utilisation d'un tableau ou d'un vecteur serait un bon choix si vous avez besoin d'un accès direct aux éléments de la structure (par exemple, l'accès à un index), mais cela ne sonne pas comme si vous en aviez besoin.
Chaque fois que vous supprimez un élément de la liste liée, vous pouvez l'ajouter à un pool d'objets qui peuvent ensuite être recyclés pour économiser sur l'allocation de mémoire.
J'ai utilisé les infrastructures de données polygonales dans plusieurs projets et j'en suis très satisfait.
Edit: Désolé, je pense que la réponse n'était pas très claire en termes de stratégie de suppression: je suggère de supprimer l'élément de la liste, dès qu'il est mort et de l'ajouter directement à la structure de regroupement (recyclage). Étant donné que la suppression d'un élément d'une liste chaînée est très performante, je ne vois aucun problème à le faire.
la source
next
pointeur au nœud après celui supprimé. Si vous ne voulez pas les tracas de le faire vous-même, une liste à double lien serait la DataStructure de choix."il suffit de mettre un drapeau dessus pour dire" saute par-dessus moi, je suis mort ". Je rassemble mes entités, donc une entité qui est morte est très susceptible d'être de nouveau en vie à un moment donné"
Je pense que vous avez répondu à votre propre question concernant cette application spécifique. Je m'éloignerais des tableaux si vous envisagez de travailler sur eux autre que push and pop. Les listes chaînées seraient une façon plus intelligente de procéder si vous envisagez d'effectuer des opérations lourdes. Cela dit, si vous prévoyez de réintégrer la même entité dans le jeu, il est logique de ne définir qu'une variable booléenne et de la vérifier pendant les boucles de fonctionnement du jeu.
la source
Une solution propre et générale que j'ai trouvée sur une bibliothèque que j'ai utilisée était d'utiliser une carte verrouillable.
vous avez 2 opérations
lock()
etunlock()
, pendant que vous parcourez la carte, vous allezlock()
, à partir de ce moment, chaque opération qui modifie la carte ne prend pas effet, elle est simplement poussée dans uneCommandQueue
qui s'exécutera une fois que vous aurez appeléunlock()
.La suppression d'une entité aurait donc le pseudo-code suivant:
et quand vous
unlock()
La seule chose à considérer est que vous ne supprimerez l'entité qu'après la boucle.
EDIT: c'est la solution proposée par Simon.
la source
Voici une réponse que j'ai obtenue de Liosan :
/gamedev//a/46765/24633
la source
J'ai deux méthodes.
Lorsque vous appelez un objet à supprimer, cela définit vraiment deux indicateurs:
1.Un pour indiquer au conteneur qu'un objet a été supprimé
2.Un pour indiquer au conteneur quels objets ont été demandés pour être supprimés
Un utilisant un vecteur d'objets
Ensuite, dans la fonction de mise à jour, vérifiez si un objet a été supprimé et si c'est le cas, parcourez tous les objets et supprimez ceux qui ont un indicateur de suppression
Deux Utilisation d'un (pointeur vers un) vecteur d'objets.
Dans la fonction de mise à jour, si un objet doit être supprimé, parcourez les objets et ajoutez ceux qui ne doivent pas être supprimés à un nouveau vecteur. supprimer le vecteur d'objets et placer le pointeur sur le nouveau vecteur
la source