Public Group

# Sprite movement

This topic is 4438 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi I've googled around to find information about sprite movement. I'm now able to do just about everything I could want with my sprites, but one problem eludes me. I cannot get the sprite to move in the direction it is "facing". Ok, I've made some testcode to make the sprite rotate and face the mousecursor when it moves around. This works like a charm, but now I want it to move towards the mousecursor. Here's the code i use to rotate:
float x = (sprTestSprite->XPOS + (sprTestSprite->width / 2)) , y = (sprTestSprite->YPOS + (sprTestSprite->height / 2)), x2, y2, x3, y3;

POINT lpPoint;
GetCursorPos(&lpPoint);
x2 = lpPoint.x;
y2 = lpPoint.y;

x3 = (x2 - x);
y3 = (y2 - y);

sprTestSprite->angledegrees = D3DXToDegree(sprTestSprite->angle);

float difference;

difference = (180 - sprTestSprite->desiredangle);

if(sprTestSprite->angledegrees < difference)
{
sprTestSprite->angle += 0.001 * Mtimer->DTime();
}
if(sprTestSprite->angledegrees > difference)
{
sprTestSprite->angle -= 0.001 * Mtimer->DTime();
}

sprTestSprite->SetPos(sprTestSprite->XPOS, sprTestSprite->XPOS);
sprTestSprite->Drawtransformed(sprTestSprite->fXscale, sprTestSprite->fYscale, sprTestSprite->opacity, sprTestSprite->angle);


I've learned from googling that I should do something like: position += direction * speed * time_step. So I tried:
sprTestSprite->XPOS += (0.01 * Mtimer->DTime()) * cosf(sprTestSprite->angle);
sprTestSprite->YPOS += (0.01 * Mtimer->DTime()) * sinf(sprTestSprite->angle);


This did not give the desired effect at all :) I've tried both radians and degrees in the last mentioned code, but nothing has come close. The sprite reacts to the cursors position, but does not close the distance between them. Can anybody see what is wrong with my code? The "difference" variable is there to make sure the sprite knows that 0 degrees is up and 180 degrees is down. A

##### Share on other sites
Quote:
 The sprite reacts to the cursors position, but does not close the distance between them.

If I understand this correctly, then what you're missing is calculating the velocity at which the sprite is moving at.

Here's some code (C# and made for PDA's, sorry :D):

      public class Ball : Sprite      {            private float yVel = 0.0f;            private float xVel = 0.0f;            private float accelX = 0.0f;            private float accelY = 0.0f;            public Ball(Display display)                  : base(display)            {                  // not important ...            }            public void UpdateMovement(Point target)            {                  if (this.Contains(target.X, target.Y))                        return;                  this.Top += yVel;                  this.Left += xVel;                  xVel += accelX;                  yVel += accelY;                  xVel *= 0.8f;                  yVel *= 0.8f;            }            // getters/setters for each member            // ...      }

      public void NewTarget(Point p)      {            target = p;            // Calculate deltas (used later for the Atan2 function)            float dX = (float)p.X - (ball.Left + (ball.Surface.Width / 2));            float dY = (float)p.Y - (ball.Top + (ball.Surface.Height / 2));            // Calculate angle in degrees            ball.AccelerationX = (float)Math.Cos(Math.Atan2(dY, dX));            ball.AccelerationY = (float)Math.Sin(Math.Atan2(dY, dX));      }

How this code is used:

Each frame, I call UpdateMovement from the ballsprite, and pass the target member. The target is set each time the stylus hits the screen by calling NewTarget and thereby also setting the sprites' direction. Im sure you can make this work for the mouse cursor instead :)

The speed the ball will travel at is determined by the amount you lessen the velocity with each UpdateMovement call, in this case 0.8.

Good luck :)

##### Share on other sites

I think maybe I wasn't clear enough in my first post. The sprite does move, but not necessarily in the direction of the mousecursor. (Follows its own strange pattern).

The sprite is supposed to have a fixed velocity, 0.01 pixel pr. millisecond, (which is used in the movement code I've tried). There is no acceleration involved.

Quote:
 ball.AccelerationX = (float)Math.Cos(Math.Atan2(dY, dX)); ball.AccelerationY = (float)Math.Sin(Math.Atan2(dY, dX));

...looks a lot like mine from where I'm sitting. I can't understand why mine is not working.

A

##### Share on other sites
sprTestSprite->SetPos(sprTestSprite->XPOS, sprTestSprite->XPOS);

Do you really want to call Set pos with sprTestSprite->XPOS used for both arguments, or should the second one be sprTestSprite->YPOS ?

##### Share on other sites
Quote:
 Do you really want to call Set pos with sprTestSprite->XPOS used for both arguments, or should the second one be sprTestSprite->YPOS ?

Good point :) Yes, the second one is supposed to be sprTestSprite->YPOS. (I must be blind :))

After correcting this the sprite does not move right though. Now it moves in a circular notion around the cursor, like the angle of movement is 90 degrees off or something. I guess I can hardcode my way out of this, but I wish I understood why my code behaves like this.

A

##### Share on other sites
Hehe - X and Y look almost the same, could have happened to anyone.

I'm suprised it still doesn't work, but I'm not exactly sure what you're trying to do. Can you post a screen shot and maybe draw an arrow point where it should move as opposed to where does move? The way you handle your angles isn't the way I'd do it, but I'm not exactly sure what you're trying to accomplish. Do you want it to turn and head straight towards the mouse cursor?

##### Share on other sites
Quote:
Original post by Attala101
Quote:
 Do you really want to call Set pos with sprTestSprite->XPOS used for both arguments, or should the second one be sprTestSprite->YPOS ?

Good point :) Yes, the second one is supposed to be sprTestSprite->YPOS. (I must be blind :))

Uh... does that actually *do* anything, anyway (assuming SetPos does what it sounds like)? :s

##### Share on other sites
Quote:
 Original post by syphHehe - X and Y look almost the same, could have happened to anyone.I'm suprised it still doesn't work, but I'm not exactly sure what you're trying to do. Can you post a screen shot and maybe draw an arrow point where it should move as opposed to where does move? The way you handle your angles isn't the way I'd do it, but I'm not exactly sure what you're trying to accomplish. Do you want it to turn and head straight towards the mouse cursor?

I'm still having problems with this. I tried hardcoding the angles and movement and it worked up to a certain point :) When it was time to implement a particle engine, things didn't work so well after all, so I went back to my original rotation/move-code.

This is what my last attempt looks like:
		float x = sprTestSprite->XPOS , y = sprTestSprite->YPOS, x2, y2, x3, y3;		POINT lpPoint;		GetCursorPos(&lpPoint);		x2 = lpPoint.x;		y2 = lpPoint.y;		x3 = (x2 - x);		y3 = (y2 - y);		float radians = atan2(x3, y3);		sprTestSprite->desiredangle = D3DXToDegree(radians);		sprTestSprite->angledegrees = D3DXToDegree(sprTestSprite->angle);			sprTestSprite->XPOS += cosf(sprTestSprite->angledegrees) * 0.09 * Mtimer->DTime();		sprTestSprite->YPOS += sinf(sprTestSprite->angledegrees) * 0.09 * Mtimer->DTime();		if((180 - sprTestSprite->desiredangle) > sprTestSprite->angledegrees)		{		sprTestSprite->angledegrees += 0.1 * Mtimer->DTime();		}		if((180 - sprTestSprite->desiredangle) < sprTestSprite->angledegrees)		{		sprTestSprite->angledegrees -= 0.1 * Mtimer->DTime();		}						sprTestSprite->angle = D3DXToRadian(sprTestSprite->angledegrees);		sprTestSprite->SetPos(sprTestSprite->XPOS, sprTestSprite->YPOS);		sprTestSprite->Drawtransformed(sprTestSprite->fXscale * RESOLUTIONX, sprTestSprite->fYscale * RESOLUTIONY, 255, sprTestSprite->angle, false);

Now the sprite moves in the general direction of the cursor, but it seems to miss more or less depending on the angle its traveling. And it also stays in one spot and "stutter" while it rotates to the desired angle.

Can anybody see what I'm doing wrong here?

Quote:
 Original post by ZahlmanUh... does that actually *do* anything, anyway (assuming SetPos does what it sounds like)? :s

Not sure what you are saying here. The SetPos memberfunction tells the sprite its position. (Should have been included in the Drawtransformed function though).

A

1. 1
2. 2
3. 3
4. 4
Rutin
16
5. 5

• 12
• 9
• 12
• 37
• 12
• ### Forum Statistics

• Total Topics
631417
• Total Posts
2999970
×