Sign in to follow this  

Achieving Smooth 2d animations

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey everyone!

This time around I'm trying to make a simple bouncing-ball-in-a-box simulation and trying to make the animation as smooth as possible.

And so i came across tons of time based techniques on the net , of which im implementing the one given in

[URL]http://www.koonsolo.com/news/dewitters-gameloop/[/URL]

now the problem is...NO smoothness at all!
I have implemented this code just as he has explained but to no effect
The animation still seems a little jumpy/jerky(especially at high speeds where i can see 3-4 flickering balls instead of 1,with huge gaps in between)

here is my event loop
currframetick = GetTickCount();
while(1)
{

if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT)
break;

TranslateMessage(&msg);

DispatchMessage(&msg);
}

run();
}




and here is the run() definition

int run()
{


loop=0;
while((GetTickCount()>currframetick) && (loop<frameskip))
{


if(ball.x < 10 || ball.x + 32 > 630) // x bounds check
ball.xv*=-1;

if(ball.y < 10 || ball.y + 32 > 470) // y bounds check
ball.yv*=-1;

ball.x+=ball.xv;
ball.y+=ball.yv;

currframetick+=tick_time;
loop++;
}

interpolation =(float)(GetTickCount()+tick_time-currframetick)/(float)(tick_time);



viewball.x = ball.x + ball.xv*interpolation;
viewball.y = ball.y + ball.yv*interpolation;

Draw(viewball.x,viewball.y)

return 1;
}




I have set frameskip = 5 , and tick_time = 4 at the beginning of my code

Any ideas??

*EDIT* tick_time =40, time for 1 update

Share this post


Link to post
Share on other sites
I think you need to spend a little time reading why he implements "frameskip" and what values that "tick_time" should have.

As a hint; "frameskip" is used so that on slow machine it can skip rendering some of the frames, so you have to determine if you want to skip ANY at all. I'd remove frameskip entirely for now unless you need it.

When you set "frameskip" to 5 you are telling it that you only want to see every 5th frame being rendered. Which when you have "tick_time = 40" == 1000/25fps means that you will only have a frame rate of 5 frames per second (fps). Which will look very jerky.

Instead if recommend you take a leaf out of his examples and define something like this:

// this allows you to quickly change the desired frame rate
const int FRAMES_PER_SECOND = 60; // change this to 60 from 25
const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;
const int frameskip = 1;

int run()
{
loop=0;
while((GetTickCount()>currframetick) && (loop<frameskip))
{
if(ball.x < 10 || ball.x + 32 > 630) { // x bounds check
ball.xv*=-1;
}

if(ball.y < 10 || ball.y + 32 > 470) { // y bounds check
ball.yv*=-1;
}

ball.x+=ball.xv;
ball.y+=ball.yv;

currframetick+=SKIP_TICKS ;
loop++;
}

interpolation =(float)(GetTickCount()+SKIP_TICKS -currframetick)/(float)(SKIP_TICKS );

viewball.x = ball.x + ball.xv*interpolation;
viewball.y = ball.y + ball.yv*interpolation;

Draw(viewball.x,viewball.y)

return 1;
}




Andy

Share this post


Link to post
Share on other sites
@NineyearCycle
I completely understand what you said there.
But setting frameskip to 1 and fps = 60 wreaks havoc on the program....
the ball crosses the screen bounds and after that rebounds back.
And the jerkiness still doesn't go away :((
is it because of the xv and xy values??
I've set both of them to 5 for now

I also tried reducing the ticks per second value and increasing the tick_time value,and strangely got better results but for extremely slow ball speed and without proper collisions.

Quote:
Original post by boogyman19946
Have you implemented a double buffer? I can only see a Draw function.



Well yes ,I'm using the page flipping technique( using directx)

Share this post


Link to post
Share on other sites
You just set xv and yv are both just 5? Ah, this explains it slightly, with FRAMES_PER_SECOND == 25 you're adding 5 to the position every FRAME, which amounts to 25*5 per second. However if FRAMES_PER_SECOND == 60 then you're adding 60*5 per second.

Instead of setting xv and yv to 5 you probably want to scale them by the target frame rate, i.e. 5/FRAMES_PER_SECOND, so that you get the rate of movement per second.
Or if you're values of xv and yv can change then you need to do xv/FRAMES_PER_SECOND when you use them to update the position of the ball.

That would explain why it "wreaks havok" :)

Below I've tried to modify the code to show you what I mean but you might want to be careful about the lines:
viewball.x = ball.x + (ball.xv / FRAMES_PER_SECOND) * interpolation;
viewball.y = ball.y + (ball.yv / FRAMES_PER_SECOND) * interpolation;

As I am not sure what exactly you're code will do with this change. I suggest trying your own code with the first change I made (in the loop) and then with the second change on the interpolation line.

Also, it might help to write out the maths on paper so that when you run the program you can step through it in the debugger and verify that it behaves as you think it should. If the paper based maths gives you a strange answer then you know that between us we've come up with the wrong answer :)


// this allows you to quickly change the desired frame rate
const int FRAMES_PER_SECOND = 60; // change this to 60 from 25
const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;
const int frameskip = 1;

int run()
{
loop=0;
while((GetTickCount()>currframetick) && (loop<frameskip))
{
if(ball.x < 10 || ball.x + 32 > 630) { // x bounds check
ball.xv*=-1;
}

if(ball.y < 10 || ball.y + 32 > 470) { // y bounds check
ball.yv*=-1;
}

ball.x += ball.xv / FRAMES_PER_SECOND;
ball.y += ball.yv / FRAMES_PER_SECOND;

currframetick+=SKIP_TICKS ;
loop++;
}

interpolation =(float)(GetTickCount()+SKIP_TICKS -currframetick)/(float)(SKIP_TICKS );

viewball.x = ball.x + (ball.xv / FRAMES_PER_SECOND) * interpolation;
viewball.y = ball.y + (ball.yv / FRAMES_PER_SECOND) * interpolation;

Draw(viewball.x,viewball.y)

return 1;
}




I hope all this is helping :)

Andy

Share this post


Link to post
Share on other sites
hey Andy,
(sorry for the late reply,college and studies tied me up >.<)
Ok so before trying your speed-scaling method , i just commented out the check for the frameskip.And the collision problem magically disappeared!!!


Maybe its due to the fact that it wasnt entering the loop in the first place
as the condition

while(GetTickCount()>currframetick && loop<frameskip)

evaluated to false when loop>0

Is it a good idea to drop the frameskip check completely????


But i implemented the speed scaling anyway,and still got erroneous results.
(I definitely know its due to my implementation but cant seem to get it fixed)


The ball vibrates vigorously while moving really really slowly(one step at a time) along the desired path

so heres what i did

int run()
{


loop=0;
while(timeGetTime()&gt;currframetick)// && (loop&lt;frameskip))
{


ball.x =(ball.xv/fps);
ball.y =(ball.yv/fps);

if(ball.x &lt; 5 || ball.x 32 &gt; SCREEN_WIDTH-5)
ball.xv*=-1;

if(ball.y &lt; 5 || ball.y 32 &gt; SCREEN_HEIGHT-5)
ball.yv*=-1;


currframetick =tick_time;
loop ;
}

interpolation =(float)(GetTickCount() tick_time-currframetick)/(float)(tick_time);


viewball.x = ball.x (ball.xv/fps)*interpolation;
viewball.y = ball.y (ball.yv/fps)*interpolation;

draw(viewball.x,viewball.y);

return 1;
}



One more thing....

So yesterday after trying everything I could , I decided to make the program completely frame based and then fiddle around with the values until I got a better preview.

After poking here and there , I DID get some smooth motion at about xv and yv =5 or 4 maybe, but i noticed one thing.

The ball appears to be a little blurred when moving at this speed.Even though its actual bouncing motion is as smooth as it can get,it looks as if it seems to be oscillating about its own center at a very high frequency,which is only noticeable if you look closely.

This blurriness was the main reason that i decided to implement time based animation.Is this unavoidable????? Is it because of our own eyes or is it some monitor refreshing problem which is normal??


Oh and by the way, I must thank you for all your help till now.
Really useful info about the frame skipping you gave there :)

*EDIT* oops forgot the source tags :)))

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

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