Comment créer des particules qui réagissent au joueur et à ses ennemis?


38

Je suis en train de créer un jeu avec mon propre moteur de jeu que j'ai écrit en C ++ et j'utilise le dernier SDK de Directx.

Le jeu est un jeu de tir spatial top-down (avec une touche assez intéressante) et je cherche à avoir une sorte d’effet nébuleuse par lequel le joueur va voler. Je veux vraiment essayer d’obtenir cette agréable sensation tactile de centaines de particules qui s’écartent du vaisseau du joueur qui les survole. Un peu comme la façon dont les particules sortiraient du chemin du joueur dans Geomtry Wars sur XBLA.

Je suis un programmeur expérimenté en matière de C ++. Cependant, je ne sais pas comment commencer à implémenter cet effet. Quelqu'un a-t-il des idées ou des choix de design intéressants à explorer? N'hésitez pas à répondre à n'importe quel degré de profondeur que vous aimez.

Réponses:


65

C'est une bonne idée. Vous auriez besoin d'une sorte de gradient de diffusion autour de votre vaisseau. Vous pouvez penser à trois modèles physiques possibles:

  1. Vous voulez que cela ressemble presque à un milieu liquide, où le gradient de pression rééquilibre, c'est-à-dire qu'une fois que vous avez passé des particules, elles retournent dans votre sillage (comme de l'eau derrière un bateau). Dans ce cas, les positions des particules sont absolues, et seule leur relation avec le joueur modifie temporairement leur position de rendu . C'est un peu comme si vous passiez une loupe épaisse sur des objets et que la diffraction semble les faire bouger, mais seulement jusqu'à ce que vous déplaciez le verre. Dans ce cas, votre vaisseau est le verre.

  2. Si vous souhaitez qu'ils s'éloignent du navire et poursuivent leur déplacement une fois qu'ils sont partis. Cela ressemble à la physique standard dans un espace généralement vide où il n'y a pas (ou très peu) de gradients de pression.

  3. Vous voulez éloigner rapidement les particules du navire à l'approche, comme dans (1) et (2), mais une fois que le navire est parti, les particules se rééquilibrent lentement pour être à égale distance du sillage.

Commun aux trois solutions : vous devez avoir un champ de diffusion qui se déplace avec votre vaisseau. Dans cet exemple, nous allons le rendre circulaire. Vous détectez ensuite le vecteur, appelez-le v1, entre le vaisseau et chaque particule dans cette région. Poussez votre particule le long de ce vecteur. La force avec laquelle vous le repousserez dépendra de sa distance au navire: utilisez 1 - v1.magnitude. Cette formule vous donnera une force linéaire, mais vous pouvez la modifier pour utiliser autre chose, comme une courbe de force circulaire qui diminue en force vers les bords. Cela lui donnerait plus l'impression qu'il y a un gradient de pression sphérique plutôt que circulaire autour du navire.

Pour la solution 1 : Tout ce que vous faites maintenant est de modifier la position de rendu de cette particule (c'est-à-dire la position de l'image-objet) à chaque mise à jour du rendu , à l'aide de ce vecteur. Parce que vous le faites de cette façon, ceci est purement un effet de rendu et n'a aucun effet sur la position réelle de la particule dans le monde. Vous ajoutez donc la position du monde au décalage de rendu (v1) et vous avez maintenant des particules bien déplacées au fur et à mesure que vous les avancez ou les rapprochez, et vous restituez en douceur les particules lorsque vous les passez (derrière vous).

Pour la solution 2 : au lieu d'appliquer simplement v1 à la position d'affichage, appliquez-le à chaque mise à jour logique , à la position de la particule. Ainsi, p1.position += v1. Donc, vous appliquez une force d'accélération à la particule, ce qui se traduit par la vitesse. Probablement, vous voudrez que la vitesse de chaque particule soit atténuée de manière à ce qu'elles ralentissent progressivement et s'arrêtent une fois que vous êtes passé. Vous pouvez voir comment cette solution produira des particules groupées dans votre nébuleuse, car elles ne rediffuseront jamais. Pas très réaliste, j'en suis sûr, car les nébuleuses comportent des gradients de pression, aussi faibles soient-elles en réalité.

Pour la solution 3: Identique à (2), mais dans ce cas, vous devrez rediffuser vos particules. Faire cela facilement est un peu une approche de force brute, mais comme ce ne sont que des particules et donc des bon à rien, vous n’aurez probablement pas besoin de couvrir une vaste zone d’intérêt (probablement seulement un rayon de playerPosition + maxPlayerSpeedPerTick, ou peu importe. zone rectangulaire circonscrit que, pour des raisons de logique). Chaque particule appliquera une force sur chaque autre particule dans la zone d'intérêt. Ils appliqueront des forces basées, encore une fois, sur leurs distances les unes par rapport aux autres. Calculez toutes les forces interparticulaires en un seul balayage sur la zone d'intérêt, puis appliquez toutes les forces en un seul balayage. Enfin, assurez-vous que vous ne réalisez ce traitement de force inter-particules que sur des particules de vitesse nulle. Et une fois qu'une particule donnée atteint une vitesse minimale,

Il existe toutes sortes de formules de diffusion, etc., mais je pense que dans ce cas, une solution simple fonctionne mieux.


Mate, malheureusement, je n'ai pas la réputation actuelle de faire passer votre réponse à l'ordre du jour (et je ne pourrais le faire qu'une seule fois, ce qui est inférieur à ce qu'il mérite). Vous avez absolument cloué ce que je cherche dans votre première solution. Réponse fantastique. Honnêtement. Merci!
Matt McDonald

Plaisir total Matt, c'est une bonne question et il vaut la peine de faire travailler son cerveau!
Ingénieur

J'ai aussi décidé que, avec très peu de changement de code, cela pourrait s'appliquer aux plus petits astéroïdes dans une ceinture. Merci encore.
Matt McDonald
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.