8
\$\begingroup\$

I'm trying to get something like the below image. As you can see, there's a highway and inside of it, there'll be some objects moving (millisecond). I guess the street behavior is like a pipeline. When the highway loads an object, it appears at the beginning and it'll be moving through the highway until it arrives in the other extreme of the highway.

My main problem is, how can I move several objects only inside of the highway?

screen capture from bloons td4 level 1

\$\endgroup\$

3 Answers 3

18
\$\begingroup\$

That depends: how do you want them to move?

The unnatural option

Define a preset path with a series of vertices and have the balloons follow the path strictly.

A more natural option

Make the balloons boids and implement crowd path following behaviour, which will have them follow the path (and not get too far from it) whilst avoiding collision with each other. Both those pages contain Java applet examples.

The author of those pages notes he cannot distribute the source code of the examples, however OpenSteer offers C++ implementations of those algorithms.

(I'm not aware of any C# boids libraries, or any decent tutorials - the best I've done is just follow code examples)

\$\endgroup\$
6
  • \$\begingroup\$ +1 for a good answer. I think that a simple path-following is the only thing that's needed to simulate the depicted behavior. Steering behaviors will come in handy, when the path suddenly gets wider or obstacles appear where the "boids" will queue up. \$\endgroup\$
    – bummzack
    Commented Aug 21, 2011 at 9:56
  • \$\begingroup\$ I think the first option it would be easier. Is it possible you can show me an example? \$\endgroup\$ Commented Aug 21, 2011 at 15:39
  • \$\begingroup\$ @oscar.fimbres: That should be quite simple. Just create a list of waypoint coordinates (eg. an array), take the first coordinate as target and move your agent into that direction. Once the agent reaches the waypoint, take the next one as target. If the agent moves with constant velocity, you can also easily map any overshoot to the next target. \$\endgroup\$
    – bummzack
    Commented Aug 21, 2011 at 19:53
  • \$\begingroup\$ Yeah, I can imagine.. I'm checking the site: enchantedage.com/node/78 Although, I can get move my sprite in that path \$\endgroup\$ Commented Aug 21, 2011 at 21:20
  • \$\begingroup\$ IMO, boids is overkill for such a simple problem. The motion at any given time is essentially 1D and not subject to even reversing direction. Any steering behavior is likely to be extremely simple and not really warrant that kind of system. Besides, the balloons wouldn't act as a flock, they act autonomously show no real attempts to maintain "flockness" -- they are just stuck on a road and all going the same direction. That's coincidence, not an explicitly programmed behavior. Treating them like a flock doesn't really make any sense even in the context of driving. Do you follow everyone? \$\endgroup\$
    – PatrickB
    Commented Aug 24, 2011 at 0:40
5
\$\begingroup\$

You need a list of points and a list of balloons

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;
         }
     }    
}
\$\endgroup\$
0
3
\$\begingroup\$

If you have a road made up of tiles with a single path ("pipeline" as you called it), then you don't need boids, avoidance, AI, or really anything super special. Just have each balloon move in the natural direction of the road tile. For example, given a starting tile with only one non-sand tile to touch, you can figure out which direction to move -- it is the direction that is "not here, not where I was, and not sand". Since your road has only two possible directions of flow, once the initial direction and tile are established, the algorithm will solve the problem.

The balloons will appear to follow each other simply because there isn't anywhere else to go. If they all move at a constant speed, then no collisions are possible. Even if they don't move at a constant speed, the "not here, not where I was, and not sand" can be have "and make sure there is enough space for me" appended.

You could generalize a little and use the tile's image as a method of extracting direction. For example, an L shaped road stripe means either "if you're going south, then turn east" or "if you're going west, turn north".

This system breaks down when you decision making to do, i.e. more than a single path that can be taken, but from your screenshot and description of the problem, that doesn't seem to be an issue. If it is a requirement for your application, then definitely invest in a more AI-centric approach.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .