Sign in to follow this  
A_Primetime_Fool

2D Sprite Movement

Recommended Posts

Hey everyone I've been working on a 2D engine for a little while now, and I've got my sprite engine working in pretty full force. Playing around with moving my sprites across the screen, I realized an inherit problem in sprite movement that I can't figure out how to get past. My resolution is 640x480, and if I were to move my sprite right 1 or 2 pixels per frame, the movement is way to slow for most games. But when I move it, say 5 pixels per second, the movement is extremely choppy. This suggests to me that the only way to get fast movement without choppiness is to use a really low resolution. What am I missing? Am I overestimating the resolution of the 2D games I'm used to, or is it something else? Thanks for any helpful discussion.

Share this post


Link to post
Share on other sites
You can smooth things out using interpolation, if your main loop is structured correctly. Modern vid-cards usually have enough oomph to drive framerates far beyond your game's update speed. For instance, if your game is updating at, say, 25 FPS and your card can drive it at 100 FPS, then the same frame is being drawn over and over for 4 frames before anything changes. During an update, if your character moves, say, 4 pixels, then you get a visual jump of 4 pixels, which can look bad. But if you structure things so that those inbetween frames are used by way of interpolation, then instead of jumping 4 pixels, the character will move by 1 pixel spread out across the 4 video frames that are drawn between updates. It's a little confusing, and I probably didn't word it very well, but you can take a look at this article on my website, which gives an overview of a loop structure first detailed by Javier Arevalo as a Flipcode tip of the day. It describes how you can store an object's Last and Next positions, calculate an interpolation factor (t) based on how far into the next frame you are, and use that factor to draw the object at intermediate positions between Last and Next, so that the object will smoothly move from one position to the next without the jarring, abrupt jump.

Edit: Oh, yeah, and you're probably not overestimating resolutions. 640x480 is pretty low res, especially for a 2D game which usually renders faster than 3D games.

Also, there is a very simple SDL sample program linked from the above article that you can use to see for yourself the effect that interpolation can have on your visual smoothness.

Share this post


Link to post
Share on other sites
Another solution is just to use time independent movement...then if your FPS is high your sprites will move smooth as silk. Just calculate a delta time for each frame and multiply each movement value by that.

Share this post


Link to post
Share on other sites
time independent movement also has the benefit of running at the same speed on different systems.

Share this post


Link to post
Share on other sites
You need to work with sub-pixel accurate movement. That was the key for me. See, if you round off to the nearest pixel on each frame, you'll get really hurky-jerky movement, either too fast or too slow or some of each off and on (BIG STEP small step BIG STEP small step, like that).

How you do that is simply change your character's X/Y coords from ints to floats. Such a simple thing, but makes a big difference (at least for me)

Of course when you go to actually draw the thing, you round it to the nearest pixel, but you keep the actual position data in floats so that you don't lose little bits here and there.

That also implies that your movement is in "Pixels Per Second" and not just "Pixels"

Share this post


Link to post
Share on other sites
I've seen the same problem many times and usually the 2 common factors are:

- Using integers for pixels movement. Such as moving 4 pixels per frame.
- Using frame dependent movement, instead of time dependent movement.

The chopiness is caused when your sprite jumps from its last position to another one without a smoot movement. When you move it 4 pixels, you're telling it to jump 4 pixels between a frame and the next, rather than moving it slowly.

Also, take in account that frames don't last the same time. Some frames last longer than others, depending on what needs to be processed. If you use frame dependent movement, then your sprite is not moving smoothly. To do that, you must use floats instead of integers, and base the movement in time. That way, even when a frame is shorter than other, you don't mind, as the movement will be updated based on the time, and it will take that into account.
So your sprite will move more in long frames, and less in short ones, giving a constant pixels/sec speed, that is, a smooth movement.

Share this post


Link to post
Share on other sites
To solve this problem I always use time independent movement. Basically that scales the movement of your objects based on the amount of time it took your system to complete a game cycle. So you'd calculate time each time through your main loop, and end up with a "last time" (oldTIme - newTime) variable (of type float!) and pass it to your update function.

Your update function might look something like...

void Update(float timeScale)
{
velocity.x = speed;
velocity.y = speed;

x += velocity.x*timeScale;
y += velocity.y*timeScale;
}




Of course you would adjust your velocity with some key input, making the vector move in what direction you'd want it to...

Share this post


Link to post
Share on other sites
Quote:
Original post by leiavoia
Of course when you go to actually draw the thing, you round it to the nearest pixel, but you keep the actual position data in floats so that you don't lose little bits here and there.

That also implies that your movement is in "Pixels Per Second" and not just "Pixels"


Alright, thanks everyone for the input. I haven't tried impementing any of this yet, so before I go on I'd like to say I'm not doubting any of your solutions, in fact I'm sure they will work. But still, conceptually there's something bugging me that I can't shake.

Say I want my sprite moving as fast as it would move if I would use my old method of incrementing by 4 frames per second. Of course in my old method, this will result in jerkiness.

Yet, if I were to use time based movement or even change my coordinates to floats and go the sub-pixel route, none of these can change the unescapable fact that my character can only change position once every frame. So even if I'm working at 60 fps (which I was using), despite what I do under the hood with floating points or timestep movement, he's still got to move 4 pixels every frame to keep up that speed (at least in my head).

So to sum it up, I can't show his movement pixel by pixel because the framerate isn't fast enough to show it in that small of an increment, yet I can't show it by more than that because it's to large of an increment to be rendered smoothly.

Again, I realize I'm just having a conceptual problem with this and your suggestions will fix things, but I'd just really like to get past this mental hurdle that I can't get through.

Share this post


Link to post
Share on other sites
4 pixels per second won't be choppy unless your actual framerate is low. If you're running at 60fps then it'll look smooth as silk.

However you really *don't* want to use time based movement for a 2d game. While its great for 3d it tends to look terrible in 2d where minor glitches and hiccups can cause the movement to look irregular. This might even be the cause of your problems, perhaps your movement or your framerate isn't contantly hitting the 60fps mark?

Share this post


Link to post
Share on other sites
I think what you are missing is that the sub-pixel movement is usually coupled with time-independent movement as well.

For instance, instead of saying "object moves 4 pixels per frame", you say "object moves 240.0 pixels per second". If you unharness the framerate and just let it run as fast as possible, the movement will move as much as needed.

Example: lets say Object moves 100 pixels per second (pps). If your (uncapped) frame rate is currently 38fps, that's 26.3 milliseconds per frame (1000ms/38fps). Then your object does the calculation:

- we moved a time increment of 26 ms.

- i'm moving at 100pps (or 0.1 pixel per millisecond)

- 26ms * 0.1ppms = 2.6 pixels traveled this frame.


Now the next frame might be a different speed because of any number of computer factors. The equation will be the same and the result a little different every frame. If you are getting really rocking FPS, your movements will be in tiny little baby steps (mabey less than one pixel even, for slow objects). If your FPS is really crappy and you are playing on a 486, your objects will leap across the screen from frame to frame! However, even though the frame rate stinks, the object is always going the same speed. It never gets that "Nintendo NES slowdown" effect when there is too much action.

Share this post


Link to post
Share on other sites
Quote:
Original post by OrangyTang
4 pixels per second won't be choppy unless your actual framerate is low. If you're running at 60fps then it'll look smooth as silk.

However you really *don't* want to use time based movement for a 2d game. While its great for 3d it tends to look terrible in 2d where minor glitches and hiccups can cause the movement to look irregular.


Actually my current implementation is with frame based movement. But anyway, what is the general consensus on that. Should 2D sprite movement be done in respect to frames or real time? At first I was using the real time approach, but then I realized that if my computer encountered some processing problems, I wouldn't want the rest of my game moving slow, while my sprite is rocketing across the screen unaffected. Of course the sprite would be just as slow to be rendered as anything else in the game, but if it was running dependant on time, its coordinates would change quickly and the sprite's position would change faster than the rest of the stuf on the screen.

So is the answer that everything in my code should be either frame or time dependant, but don't mix? I either answered my own question or confused myself even more... Haha... would anyone like to tell me which one it is?

Share this post


Link to post
Share on other sites
Quote:
So is the answer that everything in my code should be either frame or time dependant, but don't mix?

Exactly. Experiment with both to see which one you prefer and gives the better results.

Share this post


Link to post
Share on other sites
Quote:
Original post by OrangyTang
However you really *don't* want to use time based movement for a 2d game. While its great for 3d it tends to look terrible in 2d where minor glitches and hiccups can cause the movement to look irregular.


I understand what he's saying there, but i disagree to a point. The flexability that time-indepenedent movement gives you is worth it.

Quote:
So is the answer that everything in my code should be either frame or time dependant, but don't mix? I either answered my own question or confused myself even more... Haha... would anyone like to tell me which one it is?


Don't mix them. Have everything go one way or they other, and out of my personal preference, go the way of time-independence :-) If you try to mix them, you'll get some real weird things, but mostly it will just be frustrating to callibrate and coordinate objects all moving willy-nilly at whatever pace they like.

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