PDA

View Full Version : Scrolling "jerky"



Damot
23-04-2004, 05:18 PM
I'm using a Tbackground sprite for a tile based scrolling game.

The problem is it's wonderfully smooth on a Voodoo 16MB graphics card on a very old machine, but "jerks" on anything more modern.

I'd like to give you an example of what I mean, does anybody know any free website hosts that I can upload a sample program to???

Damot
23-04-2004, 07:19 PM
I've managed to upload it here:-

http://thedamot.mailcan.com/

What I don't understand is why it is so smooth on an old machine with a Voodoo card, and is very jerky on a 2ghz Athlon with 128mb graphics!

What am I doing wrong?!!

For every frame I'm calculating the amount to move the tiles, to achieve 192 pixels per second. I'm asuming that's where I'm going wrong.

Is GetTickCount not good enough for this?

Many thanks for any help.

Traveler
23-04-2004, 08:48 PM
Hi Damot,

There are a few odd things in your code. First thing I noticed is the initialisation of StartDemo. There's no need to use a timer for this. Dxdraw has an event called onInitialize. If you add the StartDemo call there, you can remove the timer alltogether.

Second, I see you're using the DXSpriteEngine to draw tiles. I recommend using DirectDrawSurface instead. For an example, have a look at the third tutorial on my website. (It also includes scrolling)

Now for the important part, the reason the movement is so jerky is because your using GetTickCount not correctly (as you already guessed). In your code, 'Moveamount' will never reach a stable point. At one clock cylce it may be 2.1, the next cycle 3.4 or perhaps even 4. Adding a threshold should do the trick.

Damot
23-04-2004, 09:23 PM
Hi Damot,

There are a few odd things in your code. First thing I noticed is the initialisation of StartDemo. There's no need to use a timer for this. Dxdraw has an event called onInitialize. If you add the StartDemo call there, you can remove the timer alltogether.

Second, I see you're using the DXSpriteEngine to draw tiles. I recommend using DirectDrawSurface instead. For an example, have a look at the third tutorial on my website. (It also includes scrolling)

Now for the important part, the reason the movement is so jerky is because your using GetTickCount not correctly (as you already guessed). In your code, 'Moveamount' will never reach a stable point. At one clock cylce it may be 2.1, the next cycle 3.4 or perhaps even 4. Adding a threshold should do the trick.

Thanks for your reply.

I've just solved it actually. I was using GetTickCount to calculate how quick the last frame was, so I could calculate an amount to move (MoveAmount) to achieve the desired X pixels per second.

I should have been using QueryPerformanceFrequency() &
QueryPerformanceCounter() to get a move acurate reading.

It's now MUCH smoother. If anyone wants to see the difference, reply here and I'll put it up.


I'll have a look at your site, thanks.

Damot
23-04-2004, 10:04 PM
Hi Damot,

Now for the important part, the reason the movement is so jerky is because your using GetTickCount not correctly (as you already guessed). In your code, 'Moveamount' will never reach a stable point. At one clock cylce it may be 2.1, the next cycle 3.4 or perhaps even 4. Adding a threshold should do the trick.

I think I replied too soon!. :-(

The little demo I uploaded there now works fine, nice and smooth, now using QueryPerformanceCounter() to calculate the speed it took to draw the last frame, so we know how much to move this time around.

But I modifed my game and it still "jerks" on an Athlon but NOT on my old Pentium. :-(

The whole point is to ensure that the game plays at the same speed regardless of he processor/graphics card.

I thought that's the technique to use?

You suggest a "threshold", but why would I need one for it to run smoothly on an Athlon, but not a slow machine? (I could understand it jerking occasionally on the old machine, but it doesn't!).

My head hurts.

Traveler
24-04-2004, 11:15 AM
There's been a discussion before, on how to deal withtimebased movement (http://terraqueous.f2o.org/dgdev/viewtopic.php?t=1163) . I think you might find it an interesting read.

Damot
25-04-2004, 09:15 AM
There's been a discussion before, on how to deal withtimebased movement (http://terraqueous.f2o.org/dgdev/viewtopic.php?t=1163) . I think you might find it an interesting read.

Yes, thanks for that. I've managed to understand and implement this technique, but I've now realised where the "jerking" is coming from.

If I just move my player around like this it's very smooth indeed, the problem comes when I need to have my player *stop* exactly on each tile.

Say my tiles are 32x32 pixels. I want my player to move from say tile 1,1 to tile 5,1 (across -right). I use this frame rate independant movement to achieve, say 128 pixels per second.

As each frame of the game happens, he might move 2.6 pixels , then 2.7, then maybe 2.4 etc as he slides *smoothly* across. This is all very well and looks great.

However, I need the player to reach each tile *exactly*. So what I've been doing is effectively snapping him to each tile as he travels across. This "adjusting" effects the overall smooth moving, causing the jerky.


So I'm a little confused on how to fix this. It's difficult explaining what I mean, but hopefully you understood the gist of what I'm getting at.

I need the player to move *onto* each tile exactly as he travels.


My head hurts. :-)

Traveler
25-04-2004, 10:33 AM
Judging by your demo, I asume you're making a platform game. If this really is the case, then I'm uncertain as to why you want to have your sprites aligned with the tiles every time they are moving.
It is in any case not what normally happens in platform games, and might be confusing to the player or perhaps even annoying, because the sprite will continue to move until it is aligned with a tile. Even when the user has stopped pressing the buttons.

I could be wrong here, but i think you need to look for a different solution.

Damot
25-04-2004, 10:59 AM
Judging by your demo, I asume you're making a platform game. If this really is the case, then I'm uncertain as to why you want to have your sprites aligned with the tiles every time they are moving.
It is in any case not what normally happens in platform games, and might be confusing to the player or perhaps even annoying, because the sprite will continue to move until it is aligned with a tile. Even when the user has stopped pressing the buttons.

I could be wrong here, but i think you need to look for a different solution.

Actually it's not a platform game and it's very important that the player doesn't stop between tiles.

But the thing is, even if it was a platform game, what would happen when the player moves along and hits a wall? He has to come to a rest exactly on a tile then (so he's up exactly against the wall) doesn't he?, so surely the same problem applies? Err.r.......






The whole system depends on that.

Traveler
25-04-2004, 01:49 PM
He has to come to a rest exactly on a tile then (so he's up exactly against the wall) doesn't he?, so surely the same problem applies? Err.r.......

In a platform game I would check for the wall. But, the sprite doesn't necessarily have to stop walking when he reaches the center of the tile. (What if your sprite is very narrow and your tiles very large)
But yes, you are right when you say that in theory the same problem applies.

If there is a wall in the sprite's path I usually calculate the number of pixel to the wall, and then use that information for the next update.

Say pixels to wall = 4, and sprite speed = 5 then in the next update the speed is not 5 but 4. (or 2 to have some room between the sprite and the wall)

I believe you could do the same thing. Detect the kind of tile in front of the current tile and handle accordingly. If there's no obstacle, do nothing, else calculate the remaining pixels (in your case to the center of the tile).

Damot
25-04-2004, 03:07 PM
He has to come to a rest exactly on a tile then (so he's up exactly against the wall) doesn't he?, so surely the same problem applies? Err.r.......

In a platform game I would check for the wall. But, the sprite doesn't necessarily have to stop walking when he reaches the center of the tile. (What if your sprite is very narrow and your tiles very large)
But yes, you are right when you say that in theory the same problem applies.

If there is a wall in the sprite's path I usually calculate the number of pixel to the wall, and then use that information for the next update.

Say pixels to wall = 4, and sprite speed = 5 then in the next update the speed is not 5 but 4. (or 2 to have some room between the sprite and the wall)

I believe you could do the same thing. Detect the kind of tile in front of the current tile and handle accordingly. If there's no obstacle, do nothing, else calculate the remaining pixels (in your case to the center of the tile).

Yes, my player is exactly the same size as a tile and I want him never to stop between a tile (like a chess piece always slides onto the the next tile).

When the player presses "right" he slides over one tile to the right and should stop, unless you're still holding "right" so you continue moving.

This only works now because I'm checking that on the next move (whatever speed) he doesn't go over and snaps to the next tile (jerkying).

I'm trying to think of a similar Windows game that plays like that so I can see one working right.

Can you/anyone think of a game where the player takes up one tile, slides between them but only allows you to stop exactly on a tile and not between?

Damot
26-04-2004, 06:34 PM
Just to let you know (if you're interested!), I've managed to solve my problem. Well, my programming one anyway! :-)

What I've done is when the player chooses to travel in a direction I make a note of a destination "stop" point (+32 pixels)

Then as he travels (at the varying pixel rate) I check to see if he has reached or exceeded the "stop" point.

If he has I then (this is the crucial bit) check to see if he is requesting and is able to travel to the next tile. If he does he simply is allowed to continue after increasing the "stop" point by 32 again.

If he dosn't want to continue, or isn't able to, I then stop him at the correct point (ie the stop point) so stopping him exceeding it. This effect means the player is never able to stop inbetween any tiles but is allowed to continue smoothly is he wishs.

The difference is amazing. Super smooth scrolling!


Thanks again for your feedback.

One question you might be able to help with, do I have to call QueryPerformanceFrequency() for every frame, or is that fixed depending on the processor?

Paulius
26-04-2004, 06:47 PM
it's constant

Damot
26-04-2004, 07:47 PM
it's constant

Cheers!

Traveler
26-04-2004, 09:14 PM
Nice to know you have solved the puzzle. :D
Any chance we can see the solution in action?

Damot
27-04-2004, 08:28 AM
Nice to know you have solved the puzzle. :D
Any chance we can see the solution in action?

Sure thing:-

http://thedamot.mailcan.com/ScrollingExample.zip

Please ignore the strange programming style.

Just use the cursor keys to move the "player" around. ESC to exit.


Cheers!

Traveler
27-04-2004, 08:59 AM
Really quite nice! The scrolling is indeed very smooth. Also the movement of the player is really nicely done. I haven't yet checked your code, but I'm going to have a look at it later.


Actually it's not a platform game and it's very important that the player doesn't stop between tiles.

I'm really wondering about the next update. Please by all means, keep us posted!

Damot
27-04-2004, 09:10 AM
Really quite nice! The scrolling is indeed very smooth. Also the movement of the player is really nicely done. I haven't yet checked your code, but I'm going to have a look at it later.


Actually it's not a platform game and it's very important that the player doesn't stop between tiles.

I'm really wondering about the next update. Please by all means, keep us posted!

Thanks. I'm pleased how it's turned out. Forget my coding, it's very messy, but the principle's right.

What I really want to do is move away from DelphiX and write my own code.

I'm not interested in 3D or anyway, just 2D stuff like this. But where do I start?