Pour ceux d'entre vous qui se souviennent de Descent Freespace, il avait une fonctionnalité intéressante pour vous aider à viser l'ennemi lorsque vous tirez des missiles ou des lasers non-homing: il montrait un réticule devant le navire que vous avez poursuivi vous disant où tirer pour frapper le mouvement cible.
J'ai essayé d'utiliser la réponse de /programming/4107403/ai-algorithm-to-shoot-at-a-target-in-a-2d-game?lq=1 mais c'est pour 2D, donc j'ai essayé l'adapter.
J'ai d'abord décomposé le calcul pour résoudre le point d'intersection pour le plan XoZ et enregistré les coordonnées x et z, puis résolu le point d'intersection pour le plan XoY et ajouté la coordonnée y à un xyz final que j'ai ensuite transformé en espace de clips et mis une texture à ces coordonnées. Mais bien sûr, cela ne fonctionne pas comme il se doit, sinon je n'aurais pas posté la question.
D'après ce que j'ai remarqué après avoir trouvé x dans le plan XoZ et dans XoY, le x n'est pas le même, donc quelque chose doit être faux.
float a = ENG_Math.sqr(targetVelocity.x) + ENG_Math.sqr(targetVelocity.y) -
ENG_Math.sqr(projectileSpeed);
float b = 2.0f * (targetVelocity.x * targetPos.x +
targetVelocity.y * targetPos.y);
float c = ENG_Math.sqr(targetPos.x) + ENG_Math.sqr(targetPos.y);
ENG_Math.solveQuadraticEquation(a, b, c, collisionTime);
La première fois targetVelocity.y est en fait targetVelocity.z (la même chose pour targetPos) et la deuxième fois c'est en fait targetVelocity.y.
La position finale après XoZ est
crossPosition.set(minTime * finalEntityVelocity.x + finalTargetPos4D.x, 0.0f,
minTime * finalEntityVelocity.z + finalTargetPos4D.z);
et après XoY
crossPosition.y = minTime * finalEntityVelocity.y + finalTargetPos4D.y;
Mon approche de la séparation en 2 plans et du calcul est-elle bonne? Ou pour la 3D, il y a une approche complètement différente?
- sqr () est carré et non sqrt - évitant ainsi toute confusion.
la source
Réponses:
Il n'est pas nécessaire de le décomposer en 2 fonctions 2D. Cette équation quadratique avec laquelle vous travaillez fonctionne également bien en 3D. Voici un pseudo code pour 2d ou 3d. Cela implique qu'une tour (tower defense) tire sur le projectile:
'aimSpot' peut être le vecteur dont vous parlez.
la source
timeToImpact
décompte à zéro.Il existe également un bon article de blog sur le même sujet: http://playtechs.blogspot.kr/2007/04/aiming-at-moving-target.html . Il contient également des échantillons plus complexes qui incluent la gravité.
L'auteur a fait plus de simplification, ce qui donne un code plus compact:
Mise à jour: l' auteur d'origine ne tenait compte que d'une racine plus importante. Mais dans le cas où une racine plus petite n'est pas négative, il en résulte une meilleure solution, car le temps d'impact est plus petit. J'ai mis à jour le code en conséquence.
la source