Comment faire bouger des objets le long d'un chemin?

7

J'essaie d'obtenir quelque chose comme l'image ci-dessous. Comme vous pouvez le voir, il y a une autoroute et à l'intérieur, il y aura des objets en mouvement (milliseconde). Je suppose que le comportement de la rue est comme un pipeline. Lorsque l'autoroute charge un objet, il apparaît au début et il se déplace à travers l'autoroute jusqu'à ce qu'il arrive à l'autre extrémité de l'autoroute.

Mon principal problème est, comment puis-je déplacer plusieurs objets uniquement à l'intérieur de l'autoroute?

capture d'écran de bloons td4 niveau 1

oscar.fimbres
la source

Réponses:

17

Cela dépend: comment voulez- vous qu'ils bougent?

L'option contre nature

Définissez un chemin prédéfini avec une série de sommets et faites en sorte que les bulles suivent strictement le chemin.

Une option plus naturelle

Faites en sorte que les ballons boids et implémentent un comportement de suivi du chemin de la foule , ce qui les fera suivre le chemin (et ne pas trop s'en éloigner) tout en évitant les collisions les uns avec les autres. Ces deux pages contiennent des exemples d'applets Java.

L'auteur de ces pages note qu'il ne peut pas distribuer le code source des exemples, cependant OpenSteer propose des implémentations C ++ de ces algorithmes.

(Je ne connais aucune bibliothèque boids C #, ni aucun didacticiel décent - le mieux que j'ai fait est juste de suivre des exemples de code)

doppelgreener
la source
+1 pour une bonne réponse. Je pense qu'un simple suivi de chemin est la seule chose qui est nécessaire pour simuler le comportement représenté. Les comportements de pilotage seront utiles lorsque le chemin s'élargit soudainement ou lorsque des obstacles apparaissent où les "boids" font la queue.
bummzack
Je pense que la première option serait plus facile. Est-il possible que vous puissiez me montrer un exemple?
oscar.fimbres
@ oscar.fimbres: Cela devrait être assez simple. Créez simplement une liste de coordonnées de waypoint (par exemple un tableau), prenez la première coordonnée comme cible et déplacez votre agent dans cette direction. Une fois que l'agent a atteint le waypoint, prenez le suivant comme cible. Si l'agent se déplace à vitesse constante, vous pouvez également facilement mapper tout dépassement vers la prochaine cible.
bummzack
Ouais, je peux imaginer .. Je vérifie le site: enchantedage.com/node/78 Bien que je puisse faire bouger mon sprite sur ce chemin
oscar.fimbres
OMI, boids est exagéré pour un problème aussi simple. Le mouvement à un instant donné est essentiellement 1D et n'est pas soumis à une direction même inverse. Tout comportement de direction est susceptible d'être extrêmement simple et ne garantit pas vraiment ce type de système. De plus, les ballons n'agiraient pas comme un troupeau, ils agissent de manière autonome et ne montrent aucune tentative réelle de maintenir le "flockness" - ils sont simplement coincés sur une route et vont tous dans la même direction. C'est une coïncidence, pas un comportement explicitement programmé. Les traiter comme un troupeau n'a pas vraiment de sens, même dans le contexte de la conduite. Suivez-vous tout le monde?
PatrickB
4

Vous avez besoin d'une liste de points et d'une liste de ballons

class Path 
{
   List<Vector2> Points;
   float[] Lengths;
   Vector2[] Directions;

   void Build()
   {
       Lengths = new float[Points.Count-1];
       Directions = new float[Points.Count-1];
       for (int i=0; i<Points.Count-1;i++)
       {
            Directions[i] = Points[i+1] - Points[i];
            Lengths[i] = Directions[i].Length();
            Directions[i].Normalize();
       }  
   }
}

class Balloon
{
     Vector2 Position;
     float StagePos;
     int StageIndex;
     Path Path;
     float Speed;

     void Update(float Seconds)
     {
         if (StageIndex!=Path.Points.Count-1)
         {
             StagePos += Speed * Seconds;
             while (StagePos>Path.Lengths[StageIndex])
             {
                 StagePos -= Path.Lengths[StageIndex]; 
                 StageIndex++;              
                 if (StageIndex == Path.Points.Count-1) 
                 {
                     Position = Path.Points[StageIndex];
                     return;
                 }
             }
             Position = Path.Points[StageIndex] + Directions[StageIndex] * StagePos;
         }
     }    
}
Blau
la source
3

Si vous avez une route composée de tuiles avec un seul chemin ("pipeline" comme vous l'appeliez), alors vous n'avez pas besoin de boids, d'évitement, d'intelligence artificielle, ou vraiment de quelque chose de super spécial. Faites simplement bouger chaque ballon dans la direction naturelle de la tuile route. Par exemple, étant donné une tuile de départ avec une seule tuile non sable à toucher, vous pouvez déterminer la direction à déplacer - c'est la direction qui est "pas ici, pas où j'étais, et pas de sable". Puisque votre route n'a que deux directions d'écoulement possibles, une fois que la direction initiale et la tuile sont établies, l'algorithme résoudra le problème.

Les ballons semblent se suivre simplement parce qu'il n'y a nulle part où aller. S'ils se déplacent tous à une vitesse constante, aucune collision n'est possible. Même s'ils ne se déplacent pas à une vitesse constante, le "pas ici, pas là où j'étais, et pas de sable" peut être "et s'assurer qu'il y a assez d'espace pour moi" en annexe.

Vous pouvez généraliser un peu et utiliser l'image de la tuile comme méthode d'extraction de la direction. Par exemple, une bande de route en forme de L signifie «si vous allez vers le sud, puis tournez vers l'est» ou «si vous allez vers l'ouest, tournez vers le nord».

Ce système tombe en panne lorsque vous décidez de faire, c'est-à-dire plus d'un chemin unique qui peut être pris, mais à partir de votre capture d'écran et de la description du problème, cela ne semble pas être un problème. Si c'est une exigence pour votre application, alors investissez certainement dans une approche plus centrée sur l'IA.

PatrickB
la source