Comment faire l'effet de puits de gravité de Geometry Wars


11

Je ne parle pas de la grille de fond ici, je parle des particules tourbillonnantes qui circulent dans les puits de gravité! J'ai toujours aimé l'effet et j'ai décidé que ce serait une expérience amusante de le reproduire, je sais que GW utilise la loi de Hooke partout, mais je ne pense pas que l'effet Particle-to-Well se fasse à l'aide de ressorts, il ressemble à une fonction de distance au carré.

Voici une vidéo démontrant l'effet: http://www.youtube.com/watch?v=YgJe0YI18Fg

Je peux très bien appliquer un effet de ressort ou de gravité sur certaines particules, c'est facile. Mais je n'arrive pas à obtenir un effet similaire à l'effet GW. Lorsque je regarde l'effet dans le jeu, il semble que les particules soient émises en grappes à partir du puits lui-même, elles spiralent vers l'extérieur autour du centre du puits et finissent par être projetées vers l'extérieur, retombent vers le puits et répètent.

Comment pourrais-je faire en sorte que les particules spiralent vers l'extérieur lorsqu'elles apparaissent? Comment pourrais-je garder les grappes de particules ensemble à proximité du puits mais les éloigner les unes des autres lorsqu'elles sont projetées vers l'extérieur? Comment pourrais-je garder les particules si fortement attachées au puits?

EDIT:
http://www.youtube.com/watch?v=1eEPl8kOXN8 <- Vidéo
https://dl.dropbox.com/u/49283213/gw.gif <- GIF du chemin des particules

J'ai désactivé la randomisation dans GW pour rendre l'effet des particules plus facile à voir, voici une vidéo d'une minute où vous pouvez voir un drain bleu-vert envoyer son tas de particules. Les particules rouges proviennent des explosions qui apparaissent normalement partout. Quelques observations que j'ai faites à partir de la vidéo:

  • Les particules sont émises depuis le centre (ou près du centre) du drain
  • Toutes les particules sont forcées dans un mouvement dans le sens horaire autour du centre, donc une sorte de mouvement tangentiel est appliqué, vous pouvez facilement le voir lorsque les particules d'explosion rouges se rapprochent du drain.

Réponses:


7

D'après la vidéo montrée, cela semble être de la simple gravité pour moi. La plupart des gens pensent que la gravité fait voler les choses vers le bas, mais en les regardant d'un point de vue plus éloigné, elles font voler les choses dans une sorte de mouvement elliptique ou en spirale autour du centre. Les particules sont toujours accélérées vers le centre, mais volent au-delà jusqu'à ce que la gravité l'oblige à revenir, encore et encore. Certaines particules volent si loin que la gravité ne les affecte plus autant et finissent par brûler avant de changer de direction.

Chaque particule a une vitesse X et Y, à laquelle chaque image est ajoutée à la gravité, en fonction de l'angle et de la distance au centre. La gravité ajoute toujours de la vitesse dans la direction (angle) du centre.

Vous avez donc pour la particule: position, vitesse
Pour le puits de gravité vous avez: position, force

À partir des positions, vous pouvez calculer l'angle entre la particule et le puits de gravité. Pour calculer l'angle, vous aurez besoin des deltas entre les deux coordonnées.

dx = particle.x - gravity.x; dy = particle.y - gravity.y
angle = atan2(dy, dx)

Cet angle est l'angle du vecteur vitesse qui doit être ajouté.

La quantité de force appliquée dépend de la distance. Pour être exact, il diminue du carré de la distance. Donc, si quelque chose est deux fois plus éloigné, seul un quart de la force est appliqué. Pour la distance, les deltas sont également nécessaires.

distance = sqrt(dx*dx + dy*dy)
force = gravity.strength / distance*distance

Vous avez maintenant la force et l'angle dont vous avez juste besoin pour les appliquer:

particle.velocity.x += force * sin(angle)
particle.velocity.y += force * cos(angle)

votre solution est assez similaire à la mienne, mais elle utilise atan, sin, cos, sqrt, ... donc cela peut devenir très lent. il vaut mieux éviter la partie atan / sin / cos, voir mon article pour en voir un (peut-être pas le meilleur) pour le faire plus rapidement.
GameAlchemist

Ce n'est pas optimisé donc c'est mieux compréhensible.
API-Beast

vous avez raison de le faire, mais je suppose que la réponse est beaucoup plus utile, surtout pour ceux qui ne sont pas forts dans les choses cos / sin, si vous mettez le pseudo-code `` optimisé '' après l'explication théorique.
GameAlchemist

Je me rends compte que le code ici n'est pas optimisé, mais il semble que vous pouvez éviter l'appel sqrt () sur la distance, car vous l'utilisez immédiatement un instant plus tard en le mettant au carré.
Kyle Baran

2

il me semble que ce qui est dessiné, ce sont des segments, pas des points. Je suppose donc que le puits éjecte un point du cercle, avec une vitesse élevée et un vecteur vitesse tangent au cercle. Et un autre point est jeté juste après, qui est lié au premier pour dessiner un segment. Je pense ensuite que les lois de la physique (Newton) sont appliquées avec une forte gravité, ce qui explique la diminution de la vitesse. Donc je suppose que vous devez vous intégrer à temps pour ce faire.

avec: C le centre du puits, R son rayon.
P1 le point que nous examinons
K est une «grande» constante que vous choisissez avec quelques essais (masse du puits).
vel0 est le vecteur de vitesse initial, tangent au cercle.
vel0 doit être élevé (faire aussi des essais)
pos0 la position initiale, sur le cercle, à l'instant t0.
: d la distance entre C et P1
: Vn le vecteur normé C P1

accx= - Vnx * K * 1 / square(d)   ; accy = - Vny * K * 1/square (d)  
velx = accx*(t-t0) + vel0x   ;   vely = accy(t-t0) + vel0y  
posx= (1/2)*accx*square(t-t0) + vel0x*(t-t0) + pos0x   ;   
posy= (1/2)*accx*square(t-t0) + vel0y*(t-t0) + pos0y   

Init: Le moyen le plus simple pour faire apparaître un nouveau point est de choisir un angle A, puis:

  pos0x= Cx +R *cos(A)  ; pos0y = Cy + R*sin(A)  
  vel0x = v0*sin(A)   vel0y =  - v0*cos(A)     v0= float constant.

mise à jour: pour chaque itération vous devez calculer:

d= square root( square(P1x-Cx)+square(P1y-Cy) )  
Vnx= (P1x-Cx)/d   ;   Vny=(P1y-Cy)/d  
acc (accx,accy) and finally pos (posx, posy)  as described above.     

pas besoin de calculer la vitesse.
peut-être que le jeu utilise une sorte de friction, alors l'équation serait différente.
notez que vous utilisez plusieurs fois cos (A) et sin (A), alors stockez-les.

donc si vous générez beaucoup de points liés deux par deux et en même temps vous changez l'angle initial A pour que la source du segment tourne autour du puits, vous vous approchez assez près de la solution, je suppose.

Edit: je pense que vous devriez d'abord essayer sans friction, cela pourrait être ok. le frottement est une force proportionnelle à la vitesse, mais ayant une direction vectorielle inversée. donc l'équation devient:

    Acc = Gravity force + Friction Force.

avec Friction Force = - constant * Vel. cela, je ne sais pas comment l'intégrer, donc j'irais pour une intégration étape par étape:

   Vel(t+dt) = vel(t) + acc(t)*dt,   
   pos(t+dt)= pos(t)+ vel(t)*dt.  

il y aura un problème de stabilité numérique, mais comme la durée de vie des particules est courte, cela ne devrait pas être un problème.


Que faudrait-il changer dans l'équation sous l'influence du frottement? J'ai quelques solutions à ce problème, mais je suis intéressé à entendre le vôtre.
Mykel Stone

0

Je l'ai finalement fait, une réplication satisfaisante du comportement des particules.

http://www.openprocessing.org/sketch/73624

L'effet EST un effet de gravité standard avec une torsion, lorsque les particules atteignent une certaine plage, une force est appliquée sur la normale tangente. cela fait que les particules "orbitent" d'une manière plutôt instable. Les particules dans l'esquisse de traitement ne brûlent pas, mais au sommet de leur orbite, c'est à ce moment qu'elles brûlent et qu'un autre tas est libéré. Merci à tous pour votre aide, même si cela ne m'a pas vraiment fourni de nouvelles informations, il est très apprécié que vous mettiez le temps et les efforts que vous avez fournis dans vos réponses. Merci encore!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.