Sign in to follow this  
Hikaru

Moving things one pixel at the time

Recommended Posts

I'm crying my self to sleep every night over this. I'm currently developing a "overhead" 2d rpg in C# & Dx9. I've locked the movement and scrolling in the game with a timer. looks something like this: if(System.Environment.TickCount - lastTick >= 1) //1 as in 1 ms { updateInput(); lastTick = System.Environment.TickCount; } This works well if i move the things in the game 2 pixels at the time. But i want to move them just 1 pixel at the time to make it smoother. The thing is that i have more than 100 fps, so it should be possible to move everything 1 pixel at the time and still have normal speed. But because of the .NET timer i can't wait less than 1 ms :/ and that makes it slow. i've tested to unlock the updateInput and just have it running in the renderloop.. That works well but will run faster/slower on other computers, which ofcourse isn't good. what would you do?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
remove the waiting and move speed*dt pixels (where dt is the timesince the last frame) rounded down, so if 0.23 seconds have passed and speed is 50pixels/second you move 11 pixels (50*0.23 = 11.5), and let 0.01 second carry over to the next frame (11/50 = 0.22)

so if frame2 runs 0.24 seconds later you'd move 50*(0.24+0.01) pixels etc.

Share this post


Link to post
Share on other sites
What you need is multiply your scrolling by the time elapsed, so that slower machines (higher tick differences) will move by bigger chunks and faster machines (lower tick differences) will move by very little chunks, smootly.

Say you want to move at a constant 100 pixels / second, this means that your movement is equivalent to:


const float oneSecond = 1000.f; // since your ticks are in ms
const float deltaTime = (System.Environment.TickCount - lastTick) / oneSecond;
const float scrollingSpeed = 100.f;
const float scrollingAmount = deltaTime * scrollingSpeed;




All your functions requiring movement, animation, etc... should always be "time based", so that it works the same on any PC.

Hope this helps

Share this post


Link to post
Share on other sites
Check out System.Diagnostics.PerformanceCounter for a higher resoulution timer option.

Also, look into time based movement. This is when you pass a delta time to your update function.

Simplified to

float fdt; // delta time
void Run()
{
while(1)
{
fdt = GetElapsedTime(); // fdt in seconds
Update(fdt);
Render();
}
}

void Update(float dt)
{
// This scales k which you choose as a speed say 30 px/s (but the units are
// whatever you want them to be but relative to the rest of your world)
x = x + k*dt;
y = y + k*dt;
}


The above makes sure that your units will move at the 30 px/s speed regardless of computer speed.

Cheers :)

Share this post


Link to post
Share on other sites

There's been many threads about timings and how to do it in a decent way. You'll need to stop thinking in the pixel space since people may use different resolutions etc. Instead, you should think that the screen output and the game engine is separate things. What you see is only an eye blink of that particular moment inside your engine.

The idea is that your game engine works at constant speed regardless of the drawn frames. The trick is to use interpolation when rendering the frame, so that the animation will be very smooth on fast machines and a little less smoother on slower machines.

The main loop goes something like, draw the time line on the paper and you'll understand.

while(gamerunning)
{
missedframes = elapsedtime * 1/fps;

if (missedframes > 1)
{
updatelogics(missedframes);

elapsedtime -= missedframe * 1/fps;
}

render(time_in_frame);

};

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