## Point to Point

Silden
Unregistered

Post: #1
In my current project I'm trying to move a sprite from one point to another point along a straight line. I've tried a number of different ways about it including trying to implement Bresenham's line algorithms but with little luck. So if you would be kind enough to look at the code below and tell me if I'm along the right path or need to go back to the drawing board.

[SOURCECODE]
void MoveObject(short x1,short y1,short x2,short y2,short speed)
{
short x=x1; // current x position on screen
short y=y1; // current y position on screen
float deltx,delty,curx=x1,cury=y1; // float positions

deltx=x2-x1; // delta x
delty=y2-y1; // delta y

deltx/=STEPCOUNT; // Stepcount, the higher the
delty/=STEPCOUNT; // divider the better the approx

while((x!=x2)||(y!=y2)) // Main mover
{
DrawObject(x,y,obj); // Draw the object at x,y

curx+=speed*deltx; // Get float current position
if(curx>x2)
curx=x2;

cury+=speed*delty;
if(cury>y2)
cury=y2;

x=curx; // Make it a short
y=cury;
}

DrawObject(x,y,obj); // Draw object in spot
}
[/SOURCECODE]

Okay, I haven't totally gone through to check the code since I just wrote it up real quick while I should be working. Feel free to hack it to pieces. Thanks!
macboy
Unregistered

Post: #2
I'm no C/C++ programmer, but could you do something like this?

[SOURCECODE]void MoveObject(short x1, short y1, short x2, short y2, short speed)
{
short x = x1;
short y = y1;
float curx = x;
float cury = y;

while(x != x2 || y != y2)
{

DrawObject(x, y, obj);

if(x < x2) { curx += speed; }
if(x > x2) { curx -= speed; }
if(y < y2) { cury += speed; }
if(y > y2) { cury -= speed; }

x = curx;
y = cury;
}

DrawObject(x, y, obj);
}
[/SOURCECODE]You've just got to make sure that x2-x and y2-y are divisible by speed.
Silden
Unregistered

Post: #3
That way does work but it's not a straight line. It's how my older versions did it but it looks kind of strange. It goes at a 45 degree angle until one of the conditions is met and then goes in a straight line (horizontally or vertically) until the other condition is met. Even the code I posted in the first one doesn't take into account a number of things, I realized later. It would only work for one quadrant.
Oldtimer
Posts: 834
Joined: 2002.09
Post: #4
What you want to do is the following:

Grab the deltas for x and y (that is, their speed of change, expressed in units per pixel (along the line)) and then move the sprite using floating point preciscion, as so:

Code:
```float xDistance, yDistance; xDistance = x2-x1; yDistance = y2-y1; float xDelta = cos (atan2(xDistance, yDistance)); float yDelta = sin (atan2(xDistance, yDistance)); float length = sqrt (xDistance*xDistance + yDistance*yDistance); // This length is the length of the line to be traveled. // You might want to do an extra check to avoid divide-by-zeroes... currX = (x1 + (xDelta * progress)); currY = (y1 + (yDelta * progress)); // Where progress is a number between 0 and 1, meaning how far you've got along the line.```

This might be a little overkill for what you want to do, but it'll pay back later - this is perfect line movement. By changing the value of change, you'll get the position on the line where 0 is at the start, 1 is at the end, and 0.5 is half-way along it. Now, progress can be modulated either by a speed, or you can say how many seconds you want it to take to travel the entire line. This also makes it easy to accelerate and decelerate on the line.

Ah, well. Check out some vector analysis, that's really good reading.
Oldtimer
Posts: 834
Joined: 2002.09
Post: #5
Oh, as for why your posted code doesn't work, I think it's because you store the positions as shorts, not floats. Try to change that first, and respect the quadrants, if you want to keep it simple.