04-11-2011, 07:54 PM
(Modification du message : 04-11-2011, 08:09 PM par Thêta Tau Tau.)
Salut,
Je connais pas l'AS, je vais donc rester au côté mathématique de la chose sans entrer dans le code. J'expliquerais juste le concept à toi de coder ça.
t=0 correspond au moment où le projectile est tiré (donc au moment où on fait tout le calcul). Un t>0 correspond donc à une projection dans le futur.
On cherche donc à ce que le creep et le projectile soit au même moment au même endroit
appelons Tc ce moment, avec c pour contact
On a donc :
(attention c'est pas du code mais juste une relation mathématique).
Ce qu'on va chercher c'est Tc, duquel on pourra déduire tout le reste.
Il peut en théorie y avoir plusieurs solutions mais on se contentera de la première trouvée (en pratique je pense qu'il y en aura rarement plusieurs d'ailleurs, à part dans le cas de creep très rapides se déplaçant en zigzag).
Les méthodes x et y du creep sont assez simples à faire (mêmes formules que celles que tu utilises déjà), mais assez lourdes donc je m'attarderais pas dessus.
Pour celles du projectile c'est impossible car on cherche justement l'angle de tir, mais on va faire sans.
Maintenant il n'y a "plus qu'à" faire varier t jusqu'à ce qu'on trouve une valeur vérifiant les équations ci-dessus. Mais en voilà une plus pratique :
L’intérêt de cette formule c'est que pour n’importe quel t elle sera positive, donc on peut remplacer le "==0" par un "< marge d'erreur" vu que trouver pile poil le bon Tc demanderais trop de puissance de calcul.
Second intérêt : cette "marge d'erreur" c'est le carré de la distance entre le projectile et le creep, donc par exemple si tu fixe ta marge d'erreur à 9, ton projectile passera à moins de 3px du creep, et vu que les sprites font plusieurs pixels, il y aura contact.
Mais... Mais... T'as pas dit qu'on connaissait pas projectile.x(t) et projectile.y(t)?
Et oui, mais ça ne pose pas de problèmes au final! Quand on va tester une valeur de t, il suffit de considérer qu'on vise à l'endroit où se trouve le creep à ce moment là (donc [creep.x(t),creep.y(t)] ). C'est un raisonnement assez bizare mais très courant en maths (cf. wikipédia).
Du coup :
1- Tu calcules xspeed et yspeed pareil que dans ton code au dessus, en "visant" [creep.x(t),creep.y(t)]
Voilà suffit maintenant de remplacer creep.x(t) et creep.y(t) de la formule pour obtenir un truc calculable. Niveau algo le plus simple serais un truc du genre (mais c'est pas du tout optimisé).
(c'est toujours pas du code utilisable c'est juste pour montrer le concept, si il y a besoin et que j'ai le temps je veut bien essayer de coder tout ça en php).
Ou sinon tu triches et tu fait des projectiles "à tête chercheuse" (qui changent de direction donc), qui sont simplistes niveau code.
Je connais pas l'AS, je vais donc rester au côté mathématique de la chose sans entrer dans le code. J'expliquerais juste le concept à toi de coder ça.
t=0 correspond au moment où le projectile est tiré (donc au moment où on fait tout le calcul). Un t>0 correspond donc à une projection dans le futur.
On cherche donc à ce que le creep et le projectile soit au même moment au même endroit
appelons Tc ce moment, avec c pour contact
On a donc :
Code :
creep.x(Tc) == projectile.x(Tc) (en considérant x(t) comme une méthode renvoyant l’ordonnée au temps t)
creep.y(Tc) == projectile.y(Tc)
Ce qu'on va chercher c'est Tc, duquel on pourra déduire tout le reste.
Il peut en théorie y avoir plusieurs solutions mais on se contentera de la première trouvée (en pratique je pense qu'il y en aura rarement plusieurs d'ailleurs, à part dans le cas de creep très rapides se déplaçant en zigzag).
Les méthodes x et y du creep sont assez simples à faire (mêmes formules que celles que tu utilises déjà), mais assez lourdes donc je m'attarderais pas dessus.
Pour celles du projectile c'est impossible car on cherche justement l'angle de tir, mais on va faire sans.
Maintenant il n'y a "plus qu'à" faire varier t jusqu'à ce qu'on trouve une valeur vérifiant les équations ci-dessus. Mais en voilà une plus pratique :
Code :
(creep.x(Tc)-projectile.x(Tc))^2 + (creep.y(Tc)-projectile.y(Tc))^2=0
on testera donc :
(creep.x(t)-projectile.x(t))^2 + (creep.y(t)-projectile.y(t))^2 == 0
Second intérêt : cette "marge d'erreur" c'est le carré de la distance entre le projectile et le creep, donc par exemple si tu fixe ta marge d'erreur à 9, ton projectile passera à moins de 3px du creep, et vu que les sprites font plusieurs pixels, il y aura contact.
Mais... Mais... T'as pas dit qu'on connaissait pas projectile.x(t) et projectile.y(t)?
Et oui, mais ça ne pose pas de problèmes au final! Quand on va tester une valeur de t, il suffit de considérer qu'on vise à l'endroit où se trouve le creep à ce moment là (donc [creep.x(t),creep.y(t)] ). C'est un raisonnement assez bizare mais très courant en maths (cf. wikipédia).
Du coup :
1- Tu calcules xspeed et yspeed pareil que dans ton code au dessus, en "visant" [creep.x(t),creep.y(t)]
Code :
projectile.x(t)=tower.x+projectile.xspeed * t
projectile.y(t)=tower.y+projectile.yspeed * t
Voilà suffit maintenant de remplacer creep.x(t) et creep.y(t) de la formule pour obtenir un truc calculable. Niveau algo le plus simple serais un truc du genre (mais c'est pas du tout optimisé).
Code :
t=0;
pas=sqrt(marge_d_erreur) / creep.speed; //C'est à la louche faudrait tester.
//On calcule projectile.xspeed et projectile.yspeed
while( (creep.x(t)- tower.x - projectile.xspeed * t)^2 + (creep.y(t)- tower.y - projectile.yspeed * t)^2 > marge_d_erreur )
{
t = t + pas;
// On recalcule projectile.xspeed et projectile.yspeed
}
projectile.targetX = creep.x(t);
projectile.targetY = creep.y(t);
Ou sinon tu triches et tu fait des projectiles "à tête chercheuse" (qui changent de direction donc), qui sont simplistes niveau code.