Comment représenter des projectiles dans un jeu vidéo?

14

Je fais un simple jeu de tir fixe, similaire à "Galaga" ,) dans le cadre d'une présentation que je fais. Je me demande quelles stratégies et structures de données les gens utiliseraient-ils pour suivre les projectiles, comme les lasers tirés du vaisseau spatial. Une implémentation très simple que j'ai utilisée auparavant est de représenter chaque projectile comme un point et de vérifier les collisions avec tous les objets de la scène.

Cependant, cela semble coûteux, dans les grandes scènes avec de nombreux projectiles; Je me demande quels autres types de stratégies ou d'implémentations sont utilisés pour ce type de cas d'utilisation. À quoi servent les jeux comme le FPS pour suivre les projectiles (balles, obus de char, etc.)?

Polaris878
la source
5
De nombreux jeux FPS supposent que les balles sont instantanées, mais il y en a qui calculent les trajectoires et le temps de trajet.
John McDonald
2
+1 c'est une excellente question, et je ne la limiterais pas nécessairement à 3d non plus.
ashes999

Réponses:

8

Pour les projectiles très rapides (comme les lasers ou les balles), vous pouvez utiliser un Ray .

Un rayon a un point de départ et un point d'arrivée. Une structure de données (très minimale) pour un rayon est:

struct Ray
{
  Vector3f start, end ;
} ;

Ressemble à ça:

entrez la description de l'image ici

(Vous pouvez également mettre en cache le vecteur de direction et la longueur, mais j'ai utilisé un defn très simple ci-dessus).

Si le rayon est un faisceau laser qui se déplace à la vitesse de la lumière, vous persisterez simplement (comme commençant à la buse du pistolet et se terminant quelque part sur un mur) pendant quelques images. Tout ce qui coupe le rayon de chaque image subit des dommages.

Si le rayon est un projectile plus lent (comme une balle, par exemple), la distance parcourue par la balle sur un pas de temps est modélisée par le rayon. Le point de départ est l'endroit où le rayon se trouve au début de l'image, et le point d'arrivée est l'endroit où le rayon sera une fois l'image terminée. Tout ce qui gêne le rayon de la balle est endommagé par la balle.

Les rayons peuvent être efficacement entrés en collision avec des sphères, des aabbes, des coques convexes, etc. Consultez mon projet Hullinator pour un programme de course réel (CTRL + Click to fire rayons)

bobobobo
la source
1
Un rayon ne fonctionne pas très bien pour de nombreux projectiles. Par exemple, tout projectile pouvant être lobé, comme les obus de char. Cependant, les rayons sont parfaits pour les projectiles à tir direct.
MichaelHouse
Eh bien, si la coquille se déplace extrêmement lentement (par rapport à une balle ou à un laser), alors oui, je la modéliserais comme un corps ordinaire (tout comme le joueur)
bobobobo
7
Techniquement, un rayon est un point de départ et une direction. Cela peut être déterminé AVEC un point de départ et un autre point, mais cela ne fait pas partie de sa définition. Par définition, les rayons sont infinis et n'ont pas de point final.
Casey Kuball
1
Vous avez raison, ce que j'ai décrit est en fait un segment de ligne , mais la plupart des gens les appellent rayons lorsqu'ils parlent de détection de collision.
bobobobo
3

L'utilisation d'un rayon fonctionne bien pour les projectiles se déplaçant instantanément tels que les balles. Pour les projectiles qui ont une vitesse plus lente comme le type que vous utiliserez pour votre jeu spatial, il est logique de simplement suivre leur position dans le monde du jeu comme vous le feriez pour n'importe quelle autre entité. Ce que je fais souvent est d'avoir une classe de base appelée Entité qui contient les propriétés de tout objet de jeu durable - position, rotation, boîte de collision, etc. l'entité super classe, pas chaque type individuel d'entité.

Pour augmenter les performances, il est très courant de conserver un pool pour tous les objets que vous créerez et détruirez souvent. Lorsque vous avez besoin d'un nouveau projectile que vous tirez de ce pool, modifiez le nouveau projectile selon vos besoins et renvoyez-le dans le pool lorsqu'il est expiré.

JPRO
la source
2

Lorsque vous souhaitez optimiser la détection des collisions, vous pouvez stocker tous les objets de jeu dans un arbre à deux ou trois dimensions . Cette structure de données rend très efficace la récupération de tous les objets dans une certaine zone.

Les arbres binaires ont cependant l'inconvénient de dégénérer facilement lorsque des objets sont ajoutés, supprimés et changent de position, vous devrez donc l'équilibrer automatiquement .

Un compromis qui serait plus facile à mettre en œuvre mais pas aussi efficace serait d'utiliser une approche basée sur des blocs. Divisez le terrain de jeu en cubes et gardez une trace des objets qui touchent chaque cube. Lorsque vous recherchez des collisions avec un objet, il vous suffit de le comparer aux listes d'objets des cubes qu'il touche (remplacez "cube" par "rectangle" pour un jeu 2D).

Philipp
la source