Sign in to follow this  
Vimm

Smooth, timed sprite movement.

Recommended Posts

A few months ago I decided to try to learn the basics of DirectX (and Direct3D) and managed to get a scrolling tiled background with an animated sprite I could move smoothly between tiles. I also added a flashing cursor that would highlight whatever tile the mouse was over, however without any timing it was just a blur. That's where I stopped, so now I'm trying to restart from scrath and actually understand every bit of code as I put it in. I have the sprite back in place and this time I decided to try using DirectInput to move it from tile to tile. While I've been able to make it move smoothly between tiles by moving its position by 1 pixel each frame until it reaches its destination, that makes its movement speed tied to whatever system it's on when I'd like for it to move the same speed on any system. For example, it should always take 1 second to move from tile A to tile B. I thought I had originally found a sample that did something similar but I discarded it because I wasn't ready for it, and now I can't seem to find anything. I suspect I could use it on my cursor as well. Could someone help point me in the right direction?

Share this post


Link to post
Share on other sites
The current system looks something like this:
distance = speed*frames
where speed is currently 1 pixel/frame. By including the number of frames, you are using frame rate dependent movement.

Moving on.

Quote:

For example, it should always take 1 second to move from tile A to tile B.

The way you worded your ideal situation suggests (assuming 32x32 tiles):

distance = speed*time_elapsed_this_frame
where speed would be 32 pixels/second.

With just a little more effort you can fill in time_elapsed_this_frame by obtaining the number of milliseconds passed since the last frame. This would give you something similar to:
distance = 32/1000 * time_elapsed_this_frame

And that should help you remove the framerate from your equation smoothing it out accross different machines.

Hope it helped.

Share this post


Link to post
Share on other sites
Okay, I think I'm starting to see it now. Right now my sprite simply has an x/y coordinate, direction, and a moving flag. When it's moving I just enable the flag and it moves in its direction 1 pixel per frame, and when its coordinate % 32 = 0 I disable the flag. Nice and simple, right? Sounds like I need to convert my coordinates to floats and add velocity.

I've done some poking around and have discovered QueryPerformanceCounter(). I've fiddled with it a bit and can now make my sprite move at a rate of one tile per second, but how do I stop its movement EXACTLY at its destination? I can't use % 32 since there's no gaurantee it'll land exactly on a muliple of 32, and thinking ahead it might be nice to be able to move in any direction, not just North, South, East, or West.

My first thought is to add a destination coordinate to the sprite, then as long as position != destination, it should move towards the destination. If I add four more directions (NE, SE, SW, NW) I should be able to calculate if it overshoots the destination and stop it right where I want it, and that should allow me to move between any two tiles in a straight line.

Am I on the right track at all?

Share this post


Link to post
Share on other sites
You are on the right track. You will run ino some slight glitches along the way, everyone does, and the changes you make to fix them will help you see what was wrong in the first place more clearly. Hopefully you will learn as you move through it gaining a better idea of how to set things up in future projects.

Good luck [smile]

Share this post


Link to post
Share on other sites
Eureka, it works! Now I can just give the sprite a destination and tell it what direction to face, then let it wander to its destination. If I place all my sprites in a list of some kind I should be able to handle any number of them now.

The problem is, now I'm getting about 12 fps and the movement looks really crappy, and that's just with one sprite. I'm using 64 x 64 sprites for my test so I tried bumping the velocity up to 256 (4x) and it moved between tiles in 3 frames. I tried not rendering the background but it made no difference, so this sprite is the only thing being rendered. This is the only change I've made and I'm not using any Sleep() commands so I have idea what would be causing it. I know the cause could be anything, but is this a common problem to see when adding timing?

Edit: Hrm, that's odd. I fired it up today and it's working like a charm. Seems I just needed a reboot for some reason.

[Edited by - Vimm on September 9, 2005 11:07:26 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this