Je crée un jeu de stratégie au tour par tour en 2 dimensions en utilisant c ++ et SFML-2.0. Le mouvement est basé sur la distance plutôt que sur la grille, avec plusieurs pièces différentes en forme de triangle qui, à un tour donné, chacune peut soit tourner en place, soit avancer.
Le mouvement fonctionnera de telle manière que le joueur sélectionne un emplacement vers lequel la pièce doit se déplacer, ce qui génère un chemin potentiel pour la pièce à prendre. Une fois que le joueur a confirmé sa décision, la pièce se déplacera le long de ce chemin jusqu'à l'emplacement souhaité. Les chemins sont limités par deux facteurs: la distance, jusqu'où une pièce peut aller, en tenant compte des virages (donc s'il y a une courbe, ce sera la longueur le long de la courbe, et non directement d'un point à un autre); et l'angle de braquage, jusqu'où la pièce peut pivoter à n'importe quel point (et jusqu'à chaque point) tout en se déplaçant (par exemple, de -30 à 30 degrés).
Ma question est la suivante: comment dois-je procéder pour déterminer la plage d'emplacements potentiels que le joueur peut sélectionner pour déplacer la pièce?
Je ne sais pas exactement quelles équations et / ou algorithme utiliser ici. Mon plan d'origine était extrêmement trop compliqué, au point qu'il était presque impossible à mettre en œuvre, encore moins à expliquer, et je suis à ce stade totalement perdu avec le projet au point mort.
Comment puis-je déterminer la portée qu'une unité peut déplacer, en tenant compte de son rayon de braquage?
Par exemple, dans l'image ci-dessous. Les lignes rouges, bleues et vertes auraient toutes la même longueur. Le cercle violet indique la plage de mouvement que l'unité peut déplacer. (La forme est probablement inexacte et les lignes ne sont probablement pas réellement de la même longueur, mais vous avez l'idée)
la source
Réponses:
Générez un champ d'écoulement ou de distance à l'aide de Dijsktra.
Essentiellement, remplissez une grille en utilisant l'algorithme Dijkstra sans destination (probablement un nom différent pour cela; je ne le sais pas). Prenez simplement chaque nœud ouvert, calculez les voisins accessibles, poussez-les sur la liste ouverte, définissez-les sur la liste fermée, mettez à jour le chemin "suivant" du nœud parent selon le cas, etc. Lorsque vous déterminez le coût pour atteindre un nouveau nœud, tenez compte des limitations de rotation.
Le résultat sera maintenant que vous avez un réseau de tous vos nœuds sur la façon de revenir au début. Les nœuds qui ne peuvent pas être atteints n'auront pas été touchés par la première étape. Les nœuds qui peuvent être atteints auront un élément "nœud suivant le long du meilleur chemin possible vers le parent" calculé afin que vous puissiez à la fois mettre en surbrillance tous les nœuds et ensuite utiliser ces informations pour afficher ou exécuter le chemin de déplacement lorsque l'utilisateur survole ou clique sur les zones en surbrillance.
la source
Une solution de force brute serait:
Donc, en commençant par le cercle bleu, vous traitez vos chemins, pour finir avec le cercle violet. Ensuite, vous pouvez utiliser ces points avec un point central sur l'unité pour créer les triangles rouges nécessaires à l'affichage de la forme. (Faire juste cette image me fait réaliser que cette forme n'est pas correcte, mais ce sera intéressant de voir ce qui est réellement correct)
la source
Je vais développer la solution de Sean dans une réponse séparée, car elle représente une approche différente de ce que je proposais initialement.
Cette solution représente probablement la méthode la plus accessible. Cela nécessite de partitionner votre environnement en nœuds. Oui, cela réintroduit une approche basée sur la grille, mais elle peut être rendue relativement fine, ou utilisée pour une détection de chemin large avec un positionnement plus fin géré dans le nœud. Plus la structure du nœud est grossière, plus la recherche de chemin est rapide.
Le gros problème ici est que vous avez en fait affaire avec le vaisseau, donc de nombreuses solutions traditionnelles d'orientation ne peuvent pas être utilisées sans modification. Ceux-ci sont généralement indépendants du chemin, en ce sens qu'ils ne se soucient pas de la façon dont vous êtes arrivé au nœud dans lequel vous vous trouvez. Cela fonctionne bien lorsque l'accélération, la décélération et le virage sont instantanés et libres. Malheureusement pour vous, tourner n'est pas gratuit. Cependant, comme il y a vraiment une information supplémentaire qui est supprimée dans cette simplification, nous pouvons la coder comme une autre variable. En physique, cela serait connu sous le nom d'espace de phase.
En supposant que 2 dimensions pour l'instant, vous pouvez extrapoler pour 3:
Normalement, vous auriez besoin d'un nœud pour chaque position de coordonnées discrète autorisée. Par exemple:
Etc. Vous construisez un diagramme de nœuds de points adjacents et les connectez par adjacence spatiale. Ensuite, vous utiliseriez l'algorithme de Dijkstra, tuant les nœuds qui dépassent la valeur de mouvement autorisée pour le tour, jusqu'à ce qu'il n'y ait plus de nœuds vivants inexplorés restant connectés aux nœuds explorés. Chaque nœud garde une trace de la plus petite distance nécessaire pour l'atteindre.
Pour étendre cette méthode afin qu'elle soit utilisable avec Rotation, imaginez ce même nodegraph en 3 dimensions. La direction Z correspond à la rotation / face et est cyclique, ce qui signifie que si vous continuez à voyager dans la direction + Z, vous revenez à votre point de départ. Maintenant, les nœuds correspondant à des positions adjacentes ne sont connectés qu'à travers la face qui correspond à cette direction. Vous parcourez les nœuds connectés aux nœuds déjà explorés comme d'habitude. Je recommanderais de limiter à N, NE, E, SE, S, SW, W, NW dans ce schéma.
Cette solution peut vous indiquer toutes les régions accessibles de l'espace, ainsi que le meilleur chemin pour y arriver, la rotation que vous avez lorsque vous y arrivez et toutes les orientations que vous pourriez avoir lorsque vous y arrivez.
Ensuite, lors de l'exécution du cheminement, vous êtes libre d'interpoler / de spline cubique pour le rendre plus authentique.
la source
Il semble que vous deviez d'abord décider de la manière exacte dont vous souhaitez que la mise en route fonctionne. Des options comme:
S'ils se déplacent à l'intérieur du cône, tournez-les d'abord, puis commencez à bouger. Il s'agit de la solution la plus facile à mettre en œuvre et à rechercher. C'est aussi moins intéressant donc je ne voudrais pas l'utiliser.
Rotation continue tout en se déplaçant, jusqu'à un total de 45 degrés. Celui-ci est beaucoup plus délicat et, espérons-le, celui que vous recherchez. L'intégration numérique sur le chemin à l'aide d'un pas de temps fixe est probablement la façon la plus simple d'aborder celui-ci. Votre cône sera limité par la rotation maximale (+ X degrés à chaque étape) et minimale (-X degrés à chaque étape).
La meilleure façon de traverser l'espace avec la seconde de ces exigences dépend en grande partie de l'environnement dans lequel ils se déplaceront. S'il y a beaucoup d'obstacles que vous devez traverser, alors les choses peuvent devenir vraiment délicates et très coûteuses. Cependant, s'il n'y en a pas, vous pouvez charger à l'avant (et même réduire progressivement) la rotation pour finir à l'emplacement souhaité.
J'ai le sentiment que je n'ai peut-être couvert que partiellement les sujets sur lesquels vous aviez une question, alors n'hésitez pas à ajouter plus dans les commentaires et je peux étendre la discussion.
la source