Sign in to follow this  
Mizipzor

Movement speed

Recommended Posts

Mizipzor    247
Im making a game here where a character moves... since Ive learnt not to make game mechanics frame based (make time based instead) I have to rework my sprites move routines. I want to make something like this:
void Critter::Move() {
	// if we are not moving, dont bother calulating, also, enough ticks since last step must have passed
	lastMoveTime = SDL_GetTicks()-lastMoveTime;
	if(!moving || lastMoveTime < Attributes.Speed)	
		return;

The move function starts with this. First we test if the move flag is set, otherwise return. Then, we check if enough ticks have passed since we last moved. The speed member of attributes says how many ticks must have passed before we can move again. I tried this and set the speed to 1... but the sprite is moving very slowly, not one pixel every tick as I intended. Anything Im doing wrong here or should I post more code?

Share this post


Link to post
Share on other sites
pragma Fury    343
Ok, so in your statement

if(!moving || lastMoveTime < Attributes.Speed)
return;


Your critter will only move if more than "speed" milliseconds has elapsed since the last Move() call.
However, you're resetting lastMoveTime every call, so basically, if you call move() 50 times and less than 1ms has elapsed between calls, nothing's gonna happen.

I would change it to this:


void Critter::Move() {
// if we are not moving, dont bother calulating, also, enough ticks since last step must have passed
DWORD dwDeltaTimeMs = SDL_GetTicks()-lastMoveTime;
if(!moving || dwDeltaTimeMs < Attributes.Speed)
return;


// else, move
doMoveStuff();

// reset the time
lastMoveTime = SDL_GetTicks();






1 px per millisecond might be a bit fast. You might want to consider using pixels/second instead of milliseconds/pixel.

Share this post


Link to post
Share on other sites
Mizipzor    247
I changed to that. It moves faster... but still dont fast enough. That is, its not moving one pixel every millisecond. Which is to fast but i plan to change it as soon as I got it working.

I tried to change the speed value, it moves slower if I put in something greater... so something is working. :P But if I have it at 1, shouldnt it move 1 pixel every millisecond?

Any ideas of what could be wrong?


void Critter::Move() {
// if we are not moving, dont bother calulating, also, enough ticks since last step must have passed
int deltaTime = SDL_GetTicks()-lastMoveTime;
if(!moving || deltaTime < Attributes.Speed)
return;

// first we pretend how the situation would look like if we were to move
int TestPosX = Pos.X;
int TestPosY = Pos.Y;

// testmove...

// collision detection cut out

// everything is fine, we can move
SetPos(TestPosX, TestPosY);
lastMoveTime = SDL_GetTicks();
}

Share this post


Link to post
Share on other sites
pragma Fury    343
Yes, you're using a milliseconds/pixel scheme, instead of pixels/millisecond.

So by increasing your Speed variable, you're basically increasing the number of milliseconds between pixels, thereby slowing your sprite/whatever down.

What you want to do is determine that number (milliseconds) based on how fast you want it to move..
So say, you want Speed to be in pixels per second:



void Critter::Move()
{
float fPixelsPerMillisecond = float(Attributes.Speed) * 0.001f; // same as dividing by 1000, but faster
DWORD dwRequiredMillisecondsPerPixel = DWORD(1/fPixelsPerMillisecond);

if(!moving || dwRequiredMillisecondsPerPixel < SDL_GetTicks()-lastMoveTime)
return;

// do move stuff
lastMoveTime = SDL_GetTicks();
}







So, if you wanted to move 60 pixels per second, the logic works out like this
fPixelsPerMillisecond = 60*.001f = 0.06
dwRequiredMillisecondsPerPixel = 1/0.06 = 16

So 16 milliseconds must pass before you move 1 pixel, resulting in a speed of 60 pixels per second.

If you wanted to move 100 pixels/second, the math works out to give you a time of 10 milliseconds/pixel.

There are of course optimizations that can be done, like pre-computing dwRequiredMillisecondsPerPixel instead of doing it every time Move() is invoked, but I leave that to you.

Also, since you're using SDL_GetTicks() and unsigned ints (DWORDS) for your timing, there'll be rounding issues.. the actual number of milliseconds you would want to wait for a perfect 60px/sec speed is 16.66666...
You may want to consider using a high-performance timing system to get finer resolution, if speed values are that important. Look around the forums, at least one person asks how to do that every day.

SDL_GetTicks() will also limit you to a maximum of 1000px/second .. which might be an issue, depending on your application.

[Edited by - pragma Fury on March 25, 2006 9:22:18 AM]

Share this post


Link to post
Share on other sites
NotAYakk    876
If you have a delay of 1 ms between moves, and 20 ms passes between calls to your "move" function, then you need to move 10 times as far.

Are you doing this?

1 ms is very tight. It is quite likely that you won't be called every ms.

Share this post


Link to post
Share on other sites
Adam Hamilton    271
Is the Critter the only thing to move or do you have others?

If you are moving two or more objects then it is more efficient to pass in a delta time calculated in the main game loop to your move function then it is to calculate it in every object that moves.

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