Obtenez des points sur une ligne entre deux points

9

Je fais un jeu spatial simple en JavaScript, mais maintenant j'ai heurté un mur concernant les vecteurs.

La vue du jeu est descendante sur une grille 2D. Lorsque l'utilisateur clique sur la grille, le vaisseau spatial volera à cet endroit.

Donc, si j'ai deux ensembles de points:

{ x : 100.2, y : 100.6 }; // the ship
{ x : 20.5,  y : 55.95 }; // the clicked coordinates

Si la boucle de jeu tourne à 60 itérations par seconde et que la vitesse souhaitée du navire est de 0,05 point par tick (3 points par seconde), comment puis-je calculer le nouvel ensemble de coordonnées du navire pour chaque tick de la boucle de jeu?

ps Je ne veux pas tenir compte de l'inertie ou des multiples vecteurs affectant le navire, je veux juste que le navire arrête tout ce qu'il fait (c'est-à-dire qu'il vole dans un sens) et se déplace vers les coordonnées cliquées à une vitesse statique.

Stephen
la source

Réponses:

8

En pseudocode:

speed_per_tick = 0.05
delta_x = x_goal - x_current
delta_y = y_goal - y_current
goal_dist = sqrt( (delta_x * delta_x) + (delta_y * delta_y) )
if (dist > speed_per_tick)
{
    ratio = speed_per_tick / goal_dist
    x_move = ratio * delta_x  
    y_move = ratio * delta_y
    new_x_pos = x_move + x_current  
    new_y_pos = y_move + y_current
}
else
{
    new_x_pos = x_goal 
    new_y_pos = y_goal
}
Tristan
la source
@Tristan: Tu veux dire goal_distdans ton ifétat?
Nate W.
21

LERP - Interpolation linéaire

J'ai donné cette réponse pour un problème similaire il y a quelques jours, mais c'est parti:

L'interpolation linéaire est une fonction qui vous donne un nombre entre deux nombres, en fonction de la progression. Vous pourriez en fait, obtenir un point entre deux points.


La grande formule - Comment la calculer

La formule générale du LERP est donnée par pu = p0 + (p1 - p0) * u. Où:

  • pu: le numéro du résultat
  • p0: le nombre initial
  • p1: Le nombre final
  • u: Le progrès. Il est donné en pourcentage, entre 0 et 1.

Comment obtenir un pourcentage

Vous vous demandez peut-être: "Comment puis-je obtenir ce pourcentage!?". Ne t'inquiète pas. C'est comme ceci: combien de temps le point prendra-t-il pour voyager pour que le vecteur de départ se termine? Ok, divisez-le par le temps qui s'est déjà écoulé. Cela vous donnera le pourcentage.

Regardez, quelque chose comme ça: percentage = currentTime / finalTime;


Calcul des vecteurs

Pour obtenir un vecteur résultant, il vous suffit d'appliquer la formule deux fois, une pour le composant X et une pour le composant Y. Quelque chose comme ça:

point.x = start.x + (final.x - start.x) * progress;
point.y = start.y + (final.y - start.y) * progress;

Calcul du temps variable

Vous voudrez peut-être que vos points voyagent à une vitesse de 0,5 point, oui? Disons donc qu'une distance plus longue sera parcourue dans un temps plus long.

Vous pouvez le faire comme suit:

  • Obtenez la longueur de la distance Pour cela, vous aurez besoin de deux choses. Obtenez le vecteur de distance, puis transformez-le en valeur de longueur.

    distancevec = final - start;
    distance = distancevec.length();

J'espère que vous connaissez les vecteurs mathématiques. Si vous ne le faites pas, vous pouvez calculer une longueur vectorielle par cette formule d = sqrt(pow(v.x, 2) + pow(v.y, 2));.

  • Obtenez le temps qu'il faudra et mettez à jour la dernière fois. Celui-ci est facile. Comme vous voulez que chaque tick vous donne une longueur de 0,5, il suffit de diviser et d'obtenir le nombre de ticks que nous avons obtenus.

    finalTime = distance / 0.5f;

Terminé.

AVIS: Peut-être que ce n'est pas la vitesse prévue pour vous, mais c'est le bon. vous avez donc un mouvement linéaire, même sur les mouvements diagonaux. Si vous vouliez faire x + = 0,5f, y + = 0,5f, alors lisez un livre de mathématiques vectorielles et revérifiez vos plans.

Gustavo Maciel
la source
Et si vous voulez que% reste à destination de votre position? SI vous ne pouvez pas utiliser le temps delta mais plutôt les coordonnées x: y.
Dave
Si vous avez calculé progresscomme indiqué dans cette réponse, il devrait être dans la 0..1plage. Il suffit de faire:progressLeft = 1.0 - progress;
Gustavo Maciel le
3

Cela peut être fait en calculant la normale de la direction puis en calculant la position actuelle via l'équation paramétrique

newPoint = startPoint + directionVector * velocity * t

Où t est le temps écoulé depuis que le navire a commencé à voyager dans la direction souhaitée. Vous pouvez également effectuer cette opération par mise à jour via

newPoint = currentPoint + directionVector * velocity * timeDelta

Et vous calculez cela à chaque image / physique / etc. mettre à jour jusqu'à ce que le navire atteigne sa destination.

hatboyzero
la source