Question about movement - Side scroller.

Started by
6 comments, last by Aardvajk 17 years, 6 months ago
I am currently writing a side scroller (simular to Super Mario) using SDL. So far I was able to scroll back and forth and stop at each end. My problem is that the movement is not very smooth, it seems to "pulsate" for lack of better words. I will leave a snippet below. Please give me some advice as to how to accomplish a smooth scroll at different scolling speeds; walking and running for example. I repeat the process below for other input also, such as moving left. while(!killApp) //bool to flag the program as dead or alive. { SDL_PumpEvents(); //Poll for events. //Create a pointer to hold event array. Uint8 *keystate = SDL_GetKeyState(NULL); //Check if user is pressing right and d simultaneously (d will make the character "run") if(keystate[SDLK_RIGHT] && keystate[SDLK_d]) { //make sure we do not run out of surface. if(viewerXpos < 7600) { //Move the surface forward 10 pixels. viewerXpos += 10; } else { //If we are at the end, do not move the surface forward any more. viewerXpos = 7600; } } //Check if the user is pressing only right. else if(keystate[SDLK_RIGHT]) { //again, make sure we do not run out of surface. if(viewerXpos < 7600) { //move forward 5 pixels. viewerXpos += 5; } else { //otherwise stay where we are. viewerXpos = 7600; } } ... }
Advertisement
My guess is it "pulsates" because you are moving either 5 or 10 pixels at a time. You'll want to spread that out a bit. One way to do that would be to have a few variables, like:
bool scrolling_right;
int scroll_amount;
int scroll_count;

When the user presses the right arrow, set the scrolling_right bool to true. Now, each time through the loop, increment the scroll_count and viewerXpos by 1 until scroll_count == scroll_amount. Once that happens, set the scrolling_right flag back to false. If the user presses the right arrow only, set scroll_amount to 5. If 'd' was held, set it to 10.

You have to then be careful and properly handle what happens if the right arrow is pressed in the middle of scrolling right, etc...

I hope that gives you an idea.
Ok, so I did as you said, and it does indeed scroll smoothly, thank you very much. Yet this introduces another problem that I am stuck on. I cannot figure out a way to make it scroll faster or slower. If I push right, it moves well, yet if I press the run button, it still scrolls at the same speed just further, because weather or not Im moving 10px or 5 ahead, im still only incrmenting the viewer by one 1px 10 times or 5 times. Any Ideas on how I can move faster without loosing my smooth scroll?

Try this then. When running, increment scroll_count and viewerXpos by 2 instead of 1.
[EDIT] Removed a bit because Mantear got there first [smile].

10 pixels does seem quite a lot to scroll per frame. Perhaps that was why it was jerky before.

As a related but aside remark, generally with a side scroller you would move the player character an amount each turn in world co-ordinates, then anchor the top left of the viewport relative to the character. You then translate from world co-ordinates to screen co-ordinates relative to this top left point in order to draw.
Thanks Guys, I got it now.


EasilyConfused, Thank you for your comment as this is my first game, right now I'm just creating a world. I do not have a character in it yet. I am making sure my engine that puts background elements and things on the screen is working properly. Eventually the viewport will be based on the position of the character, but the movement will be simular, just based on the position of the character as apposed to keyboard input.

Thank you both for your input though, it has been most helpful
Why don't you just get the pixel distance the character moves (say, 1 pixel per 50 milliseconds for walking and 2 per 50 milliseconds when running) each frame, and then blit the background and objects at that offset, like this:

If 50 milliseconds have passed:      If the player is walking, move 1 pixel left or right      If the player is running, move 2 pixels left or rightBlit the background and objects at their position, minus the player's positionBlit the player at the center of the screen


The above would have the player always being displayed at the center of the screen, but would scroll objects and the background very smoothly.
my siteGenius is 1% inspiration and 99% perspiration
I didn't want to get too complex before, but since we are now on the subject, to expand upon the last post a bit:

At the top of your frame code, calculate the time elapsed since the last frame. QueryPerformanceCounter or timeGetTime provide fairly easy ways to do this. Work out a float value that represents the amount of a second from 0.0 to 1.0 since the last frame.

If you then define how many pixels per second your character moves when it walks and when it runs, you can then just multiply this value by the time delta calculated above to find out how far to move the character that frame.

The advantage to this is that your game speed becomes independant of the actual frame rate, which will vary tremendously from computer to computer, and even from frame to frame on the same computer as your OS may do things in the background, or you may be drawing more images one frame than another.

If there are any aspects of the above you are having trouble with, post and I can guarantee you will be inundated with responses as this is a popular subject on these forums. It's round here I got taught how to write games this way.

HTH Paul

This topic is closed to new replies.

Advertisement