Imaginez un shoot-em-up très simple, quelque chose que nous savons tous:
Vous êtes le joueur (vert). Votre mouvement est limité à l' X
axe. Notre ennemi (ou ennemis) est en haut de l'écran, son mouvement est également limité à l' X
axe. Le joueur tire des balles (jaunes) sur l'ennemi.
J'aimerais implémenter une IA pour l'ennemi qui devrait être vraiment bonne pour éviter les balles des joueurs. Ma première idée a été de diviser l'écran en sections discrètes et de leur attribuer des poids:
Il y a deux poids: Le "poids de balle" (gris) est le danger imposé par une balle. Plus la balle est proche de l'ennemi, plus le "poids de la balle" ( 0..1
, où 1 est le plus grand danger). Les voies sans balle ont un poids de 0. Le deuxième poids est le "poids à distance" (vert lime). Pour chaque voie, j'ajoute le 0.2
coût de déplacement (cette valeur est maintenant un peu arbitraire et pourrait être modifiée).
Ensuite, j'ajoute simplement les poids (blancs) et je vais dans la voie avec le poids le plus bas (rouge). Mais cette approche a un défaut évident, car elle peut facilement manquer des minima locaux car l'endroit optimal où aller serait simplement entre deux balles entrantes (comme indiqué par la flèche blanche).
Voici donc ce que je recherche:
- Devrait trouver un moyen de traverser la tempête de balles, même quand il n'y a aucun endroit qui n'impose une menace de balle.
- L'ennemi peut esquiver les balles de manière fiable en choisissant une solution optimale (ou presque optimale).
- L'algorithme doit être en mesure de prendre en compte la vitesse de déplacement des balles (car elles peuvent se déplacer avec des vitesses différentes).
- Façons de modifier l'algorithme afin que différents niveaux de difficulté puissent être appliqués (idiot aux ennemis super-intelligents).
- L'algorithme devrait permettre des objectifs différents, car l'ennemi ne veut pas seulement échapper aux balles, il doit également pouvoir tirer sur le joueur. Cela signifie que les positions où l'ennemi peut tirer sur le joueur devraient être préférées lors de l'esquive des balles.
Alors, comment aborderiez-vous cela? Contrairement à d'autres jeux de ce genre, j'aimerais avoir seulement quelques ennemis, mais très "qualifiés" au lieu de masses d'ennemis stupides.
la source
Réponses:
Je pense que votre idée de base est saine, mais ce n'est pas analogique. Vous avez besoin d'un champ de valeur analogique qui traverse l'écran. Donc, gradient de diffusion 1D, à partir duquel vous pouvez dériver une valeur à un point exact sur cette ligne, à la volée. Les gradients de diffusion sont bon marché et peuvent être utilisés par plusieurs ennemis à la fois, car ils décrivent l'environnement, et non la vue de l'entité (un peu comme l'éclairage de radiosité) - probablement pourquoi vous avez opté pour l'approche que vous avez dans votre question . Ce gradient doit être relativement lisse, afin d'évoquer le mouvement organique de l'ennemi, et se met évidemment à jour comme le fait votre gamestate. Peut-être une moyenne mobile ?
Le gradient doit combiner:
Pour esquiver, il faut pouvoir trouver une solution avec précision chaque fois qu'une solution existe . Tel est le cas chaque fois qu'il y a un espace suffisamment petit pour que l'ennemi puisse l'esquiver. Autrement dit, vous ne pouvez faire que ce que vous pouvez faire, donc l'approche par gradient ne fonctionnera pas pire que toute autre approche dans ce sens, je dirais.
Le gradient de diffusion devrait pousser l'ennemi vers des optima locaux (étant les pics du graphique) avec moins d'impératifs de déplacement, plus nous nous rapprochons d'un minimum local, d'où un effet de rendement décroissant sur l'esquive. Cela ouvre la porte à une prise de décision plus intelligente quant au moment où l'ennemi a une bonne ouverture au feu.
Si le besoin de tirer est plus grand que le besoin de bouger, faites-le; votre code peut également déterminer cela en fonction de leur différence. Vous pouvez l'implémenter dans le cadre du graphique de base, auquel cas la position du joueur réduit les valeurs environnantes dans le graphique (en supposant que les ennemis gravitent au point le plus bas), qui combine toutes les décisions dans un graphique, ou vous pouvez conserver le " graphique "désir de tirer" distinct du graphique principal "désir d'esquiver", qui vous offrira un contrôle plus direct.
IRL, je ne prendrais pas la peine d'esquiver un projectile jusqu'à ce qu'il soit à une distance que je sais, à ma vitesse d'esquive maximale, commence à devenir difficile à éviter. Expérience de première main en lançant des pierres comme un garçon. Une balle à une distance x se déplaçant à la vitesse y a le même indice de danger qu'une balle à une distance 2x se déplaçant à 2 ans. Cela doit donc être pris en compte correctement.
Les moyens de modifier l'algorithme pour la difficulté de l'ennemi incluent
Encore une fois, vous pouvez soit implémenter tous les facteurs dans un graphique (moins de contrôle et moins utile pour plusieurs ennemis), soit dans plusieurs graphiques que vous regardez ensemble pour obtenir les résultats (plus modulaires, fonctionnent probablement mieux pour plusieurs ennemis). Il est difficile d'être plus précis, car il existe de nombreuses directions dans lesquelles vous pouvez adopter cette approche.
la source
Cela peut être considéré comme un problème de cheminement. Au lieu de penser à la façon dont le méchant évite les balles, l'imagerie des balles est statique et le méchant doit les traverser jusqu'au bas de l'écran.
E = ennemi
B = balle
P = joueur
* = options de chemin vers le bas de l'écran
Une fois que le méchant a tracé un chemin réussi, il lui suffit de passer à l'étape suivante à chaque fois. Il existe probablement déjà de bons algorithmes pour trouver un chemin comme celui-ci. Si le méchant se déplace à la même vitesse que les balles, un exemple d'algorithme pourrait être;
Commencez par le baddy et marquez les positions de sécurité dans les espaces vides en bas à gauche, directement en dessous et en bas à droite. Considérez ensuite chaque espace sûr que vous venez de créer et répétez. Si à tout moment vous trouvez qu'il n'y a pas d'espaces sûrs ci-dessous, marquez l'espace comme non sûr et revenez en arrière.
la source