Author Topic: Sprites Following each other.  (Read 3831 times)

SeiferTim

  • Contributor
  • ****
  • Posts: 253
  • Karma: +0/-0
    • View Profile
    • Tim's World
Sprites Following each other.
« on: Tue, Sep 29, 2009 »
So, in working on my top-secret project, I'm trying to make a series of FlxSprites that follow each other, and I'm running into all kinds of problems.

Here's what I have:

I have 1 FlxSprite object which is sort of the 'leader', when it's created, it creates an array of other FlxSprite objects which it will handle in it's update function.

Code: [Select]
//inside the constructor:

tail = new FlxArray();
var o:FlxSprite = this;
for (var i:int = 0; i < 6; i++)
{
if (i > 0)
o = tail[i - 1];
var b:TailSprite = new TailSprite(i,o,this);
b.x = x -(5+(5*i));
b.y = y + height + (5+(5*i));
Tail.add(b);
}

These are all added to the FlxG.state a little later on.
So the TailSprite object takes "id", which is the ID # of the Sprite, which I use for some minor stuff, and "followee" which links to the sprite it's following, and "parent" is the Leader sprite that controls them all.

So, the first TailSprite's followee ends up being the leader, the second TailSprite's Followee is the first TailSprite, etc.

I've gone through about a dozen different attempts at this, and the code that I've finally got to work *sort of* like what I'm looking for looks like this:

Code: [Select]
for (var i:int = tail.length - 1; i >= 0; i-- )
{
if (tail[i].followee.visible)
{
var nP:Point = new Point(0, 0);
if (nP.x != tail[i].x || nP.y != tail[i].y)
{
if (velocity.x < 0)
nP.x = tail[i].followee.x + tail[i].followee.width - (tail[i].width/2);
else if (velocity.x >0)
nP.x = tail[i].followee.x - (tail[i].width / 2);
else
nP.x = tail[i].followee.x + (tail[i].followee.width/2) - (tail[i].width/2);

if (velocity.y < 0)
nP.y = tail[i].followee.y+tail[i].followee.height- (tail[i].height/2);
else if (velocity.y >0)
nP.y = tail[i].followee.y - (tail[i].height / 2);
else
nP.y = tail[i].followee.y + (tail[i].followee.height/2) - (tail[i].height/2);


if (velocity.x == 0 && velocity.y == 0)
{
//not moving
if (facing)
nP.x = tail[i].followee.x - (tail[i].width / 2);// - (tail[i].followee.width) - (tail[i].width / 2);
else
nP.x = tail[i].followee.x + tail[i].followee.width - (tail[i].width/2); // - (tail[i].followee.width) - (tail[i].width / 2);
nP.y = tail[i].followee.y+tail[i].followee.height- (tail[i].height/2);
}

if (tail[i].visible)
{
tail[i].x = nP.x;
tail[i].y = nP.y;
}
else
{
if(nP.x != home.x || nP.y != home.y)
tail[i].visible = true;
else
{
tail[i].x = home.x;
tail[i].y = home.y;
}
}
}
}
else
{
if (tail[i].x + (tail[i].width / 2) != home.x || tail[i].y + (tail[i].height / 2) != home.y)
{
tail[i].x = home.x - (tail[i].width / 2);
tail[i].y = home.y - (tail[i].height / 2);
}
else
{
tail[i].visible = false;
}
}
}


So, what I'm doing is trying to figure out which way the leader is moving. If it's moving to the left, I want each tail piece to be slightly to the right, and vice-versa, and similarly for up and down.

Now, the leader is going to move around the screen almost randomly, and the tail is going to follow. When the leader reaches a given place - the home.x and y, then it's going to go invisible. I want each tail segment to only also go invisible when they reach that same point, so it's checking those things as well.

Now, this sort of works, except the segments are pretty rigid, and when the leader is moving (sometimes it stops), the tail sort of jerks a bit, like it can't tell where it's supposed to be, but ultimately doesn't looks a fluid as I would like...

The leader is also a problem, currently, he moves in a straight line from point to point, either up, down, left, right, or diagonally, and he doesn't have much variation.

I tried doing some things with thrust, and angles, and making the leader move a lot more fluidly, but that caused all sorts of problems... so he's mostly saying "velocity.x = 50 | velocity.y = -50" or some combination of that.

Some things I would like to try and solve:
Anyone know why the tail is jerking when it moves?
Anyone have a suggestion for making my leader move more naturally?
Anyone have a suggestion on how to make the tail "wiggle", or otherwise move in a way that would make it look better?

I'm feeling a little frustrated, since I can see what I want to achieve in my mind, but nothing seems to be working...
Thanks.

allenp

  • Guest
Re: Sprites Following each other.
« Reply #1 on: Tue, Sep 29, 2009 »
Hey so I'm also working on a super secret project but wanted to share this code with you. I have some sprites that move between points in a sort of wavy motion.

This should all be in your update function on the head sprite or tail sprite:

Code: [Select]

// the waypoint is an object that basically represents a circle, it has an x, y, and a radius
// the waypoint x and y are the top left corner
var wpX:Number = 0;
var wpY:Number = 0;
var distX:Number = waypoint.x + waypoint.radius - x + 8; //+8 because my sprite is 16 wide
var distY:Number = waypoint.y + waypoint.radius - y + 8;

var distT:Number = Math.sqrt(distX*distX + distY*distY);

if (distT > 10) {
// do nothing
wpX = waypoint.radius;
wpY = waypoint.radius;

} else {
wpX = wpOffset.x; // wpOffset is a Point that is randomly selected near my waypoint
wpY = wpOffset.y;
}
var deltaX:Number = .001 + (waypoint.x + wpX) - (x);
var deltaY:Number = .001 + (waypoint.y + wpY) - (y);

var rX:Number = 1;
var rY:Number = 1;

if (Math.abs(velocity.x) < .5){
rX = Math.random() * 25;
}

if(Math.abs(velocity.y) < .5){
rY = Math.random() * 25;
}

velocity.x += deltaX + rX;
velocity.y += deltaY + rY;

My sprite has these settings:
Code: [Select]
maxAngular = 120;
angularDrag = 400;
maxThrust = 100;
drag.x = 40;
drag.y = 40;

maxVelocity.x = 40;
maxVelocity.y = 40;

I hope that helps with some of variation you need in getting from point A to point B.

browny

  • Guest
Re: Sprites Following each other.
« Reply #2 on: Wed, Sep 30, 2009 »
Hi Tim,

Have you thought of using steering behaviors?

Here is an example of the LeaderFollow behavior (Java applet) (There are more behaviors):

http://www.red3d.com/cwr/steer/LeaderFollow.html

This uses a library called open steer that ist already ported to flash (as3steer). There is also papersteer but I think you should use as3steer. (same author) . If someone could integrate open steer in flixel that would be very helpfull.
Open steer can handle 2d and 3d so it's a little oversized but I think it's fast enough.

Link to documentation from the original author !! Very Very interesting:
http://www.red3d.com/cwr/steer/


Link to as3steer:
http://code.google.com/p/papersteer/source/browse/#svn/trunk/branches/as3steer/src

Link to the c++ Port.
http://opensteer.sourceforge.net/


SeiferTim

  • Contributor
  • ****
  • Posts: 253
  • Karma: +0/-0
    • View Profile
    • Tim's World
Re: Sprites Following each other.
« Reply #3 on: Wed, Sep 30, 2009 »
Hi Tim,

Have you thought of using steering behaviors?

Here is an example of the LeaderFollow behavior (Java applet) (There are more behaviors):

http://www.red3d.com/cwr/steer/LeaderFollow.html

This uses a library called open steer that ist already ported to flash (as3steer). There is also papersteer but I think you should use as3steer. (same author) . If someone could integrate open steer in flixel that would be very helpfull.
Open steer can handle 2d and 3d so it's a little oversized but I think it's fast enough.

Link to documentation from the original author !! Very Very interesting:
http://www.red3d.com/cwr/steer/


Link to as3steer:
http://code.google.com/p/papersteer/source/browse/#svn/trunk/branches/as3steer/src

Link to the c++ Port.
http://opensteer.sourceforge.net/



That's pretty neat, but not quite what I'm going for...
I'm trying to make it so the 'leader' is sort of connected to all the tail pieces as if there's a rope between them, and when the head moves, it pulls all the other pieces with it...

I've been able to come up with something that sort of works like I envisioned... it's not perfect, but its close enough for me to not want to risk breaking it to mess with it any more...

Wish I'd paid more attention in Trig... :P

ETG

  • Active Member
  • ***
  • Posts: 115
  • Karma: +0/-0
    • View Profile
Re: Sprites Following each other.
« Reply #4 on: Wed, Sep 30, 2009 »
You could set up a command buffer. Have the head record the change in position each frame (and possibly the elapsed time could come in handy too) into an array that the tail piece keeps to follow at a later time. You can pass the movements down the tail segments and they will all go where the head goes, but at a later time.

Take a look at the steering behavior. You could do something similar to that to cause the wiggle you want. Each segment can have an wiggle vector or an offset (small circles?) that it moves in addition to the buffered movement. This would be why you might save the elapsed time, so you can wiggle it based on the timing of the buffered movement.

xmorpher

  • Member
  • **
  • Posts: 39
  • Karma: +0/-0
    • View Profile
Re: Sprites Following each other.
« Reply #5 on: Wed, Dec 16, 2009 »
it sounds like a "snake" game... check out this tutorial: http://www.strille.net/tutorials/snake/index.php

SeiferTim

  • Contributor
  • ****
  • Posts: 253
  • Karma: +0/-0
    • View Profile
    • Tim's World
Re: Sprites Following each other.
« Reply #6 on: Wed, Dec 16, 2009 »
Yeah, we solved this problem, and our 2nd boss in Blasting Agent features this type of movement... can't wait to show him off! :D