Supposons que vous avez un jeu dans lequel de nombreuses entités remplissent certaines fonctions, mais toutes ne sont pas toujours nécessaires ou doivent être prises en compte dans chaque cadre. Le problème concret sur lequel je travaille et dans lequel ce numéro est présent est une simulation détaillée d'un corps, y compris de ses organes.
Dans le jeu, chaque créature a son propre corps qui est séparé en parties plus petites (torse, jambes, etc.) et parfois, ces parties contiennent des organes qui remplissent une fonction spécifique dans le corps. On ne sait jamais vraiment si un organe sert ou a un rôle ou est actif. Après tout, un animal peut avoir l'estomac vide, qui n'a donc besoin de rien digérer. Il serait assez ridicule de vérifier ou de simuler chaque objet dans chaque cadre et très coûteux dès que vous avez plusieurs créatures dans le monde. Je réfléchissais donc à un moyen de différencier intelligemment les objets qui doivent être mis à jour de ceux qui ne le sont pas.
Ce que j'ai proposé semble être une solution au moins satisfaisante. Il crée une simple file d'attente / pile (l'essentiel est que chaque élément soit supprimé dès sa lecture; l'ordre n'est pas important) appelé "pile d'attention" où résident les objets à simuler. Les objets qui nécessitent une attention seraient simplement mis sur la pile ou y sont mis par d'autres objets. Ces objets implémenteraient probablement une interface simple avec une fonction simulate ().
Appliqué à mon exemple de digestion précédent, cela signifierait:
Le joueur choisit quelque chose à manger (supposer que c'est du pain) dans l'inventaire et le met dans la bouche de son personnage. La bouche est ensuite mise sur la pile d'attention. Dans l'image suivante, la bouche est extraite de la pile et sa fonction simulate () est appelée. Comme c'est une bouche, il serait raisonnable de simuler la mastication ici. Cela pourrait durer quelques images dans lesquelles la bouche continue de se mettre sur la pile jusqu'à ce qu'elle décide que la nourriture est prête à être avalée. Dans ce cas, la bouche met le pain mâché dans l'estomac (je sais qu'il ne s'y rend pas directement, mais l'œsophage est laissé de côté pour simplifier), qui est ensuite également placé sur la pile d'attention. Dans la trame suivante, la simulation du processus de digestion est lancée. Et ainsi de suite pour le reste des organes nécessaires.
Un problème prévisible avec ce sont les objets inactifs. Un animal endormi en est un bon exemple. Cela pourrait se faire comme décrit précédemment en gardant l'animal endormi sur la pile et en vérifiant à chaque fois s'il doit se réveiller, mais cela semble inutile, car c'est la seule chose à faire. Pour rendre les objets inactifs plus efficaces, je prévoyais d'ajouter une sorte de planification qui stockerait les tâches à exécuter à une heure spécifique. Si un animal s'endormait, il mettrait un travail à cet horaire qui serait planifié pendant un certain temps après que l'animal se soit endormi. Ce travail prendrait alors soin de remettre l'animal endormi sur la pile d'attention. Maintenant, vous pouvez dire qu'un animal endormi qui ne se trouve pas sur la pile d'attention pourrait ne pas être attaqué par quelque chose parce que son IA n'est pas simulée,
Maintenant, honnêtement, je ne sais pas si cela est encore proche d'une solution élégante à ce problème en raison d'un manque d'expérience. Suis-je près de quelque chose utilisable? Comment cela se fait-il habituellement ou quelqu'un a-t-il des suggestions ou de meilleures solutions?
la source
Cela ressemble à un problème similaire à celui des entrées: vous avez plus de 100 touches sur le clavier mais vous ne voulez pas vérifier chaque touche sur chaque image, que faites-vous?
Deux réponses: interrogation ou messages système.
Polling = à n'importe quel moment où cela compte vraiment dans le jeu, interrogez l'état des touches du clavier (ou des objets, dans votre cas). Le reste du temps, ignorez-les.
Messages = demander à chaque touche du clavier (objet) de mettre quelque chose dans une file d'attente de messages lorsqu'il est enfoncé ou relâché (lorsqu'il a besoin d'attention). À chaque itération de la boucle de jeu, il regarde dans la file d'attente et résout tous les messages avant de continuer.
la source
Je vais donc prendre du recul par rapport à la mise en œuvre et examiner la question du point de vue de la conception. Avez-vous un plan solide pour afficher tous les détails que vous souhaitez inclure dans cette simulation?
Par exemple:
En gros, la règle générale est de ne pas rendre votre simulation plus compliquée que ses résultats. À la fin de la journée, si les seules animations que vous avez pour les moutons sont paître, dormir, fuir. Alors, peu importe le nombre de facteurs entrant en ligne de compte dans la décision de choisir l'état. Tous les joueurs vont voir ce sont des moutons qui dorment la nuit, fuient le danger et mangent le jour.
La simulation de comportement est une activité très amusante, mais gardez toujours à l'esprit l'expérience des utilisateurs finaux.
la source
J'ai eu un problème similaire sur un jeu sur lequel j'avais travaillé il y a quelques années: la simulation d'objets était complexe et ne pouvait pas vraiment être réalisée en détail sur tous les objets du monde.
La solution consistait à utiliser le concept LOD pour la simulation. Les objets dans la vue du joueur exécuteraient la simulation complète. Les objets éloignés du joueur exécutaient périodiquement une simulation hautement simplifiée. À mesure que les objets se présentaient à la vue du joueur, ils passaient d’une mise à jour périodique de simulation à une mise à jour détaillée et régulière.
la source
La solution avec un calendrier est bonne. Notez que chaque entité doit avoir une liste de pointeurs vers ses actions futures, ce qui permet d'invalider les actions futures si nécessaire. C'est à dire. Un animal endormi se réveille instantanément lorsqu'il est attaqué. Vous devez donc invalider son action de réveil à l'avenir.
la source
Il y a un modèle de conception pour cela. Je pense que cela s'appelle des objets de base de données?
En gros, vous conservez un mouton "modèle" qui peut représenter tous les moutons non spéciaux du monde du jeu, vous les dessinez tous de la même façon, en conservant les données uniques dans l'objet modèle, par exemple sous forme de tableau des emplacements et / ou de l'heure du mouton. -since-cisaillement Ensuite, chaque fois que vous devez rendre un mouton unique, vous pouvez créer une instance spécifique pour suivre ce mouton unique.
La même chose vaut pour les animations. S'il s'agit d'une animation ou d'un événement inactif commun à toutes les instances, il peut résider dans l'instance de modèle, où des animations plus spécifiques peuvent être planifiées séparément.
Il y a longtemps, j'ai écrit un jeu pour un concours de programmation dont la boucle principale s'appelait animate () sur toute la scène. Il a utilisé des pointeurs de fonction pour remplacer les animations inactives par d'autres, selon les besoins, et a utilisé la technique pour prendre en charge l'animation héritée (par exemple, faire pivoter un personnage qui se tient sur un disque en rotation).
Cela ressemble par nature à l’utilisation d’un délégué pour l’animation.
la source
Une machine d'état fonctionnerait-elle? L'animal est soit en état de sommeil, en état de manger, en mouvement, etc. Pour chaque état, vous associez une liste d'organes actifs. Donc, chaque image que vous visitez, chaque animal, allumez l’état, la liste de recherche d’organes pour cet état et exécutez la mise à jour sur chacun des organes.
la source