Jump to content
  • Advertisement
Sign in to follow this  
nullsquared

SDL movement(too fast or too slow)

This topic is 4817 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

Hi all! I'm using SDL in C++, in Dev-Cpp, on windows XP, uhh thats enough, right? For some reason once the people in my game moved normally, but now that my pc is faster, they move around the screen in just seconds. Can anyone tell me how to control the speed, so its the same always? Heres the code just in case:
[source language="cpp"]
#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_mixer.h"

SDL_Surface *screen;

void Draw(int x, int y, SDL_Surface *sprite);

int main(int nArgs, char **args)
{
    Mix_Music *bgSound;
    
    Uint8* keys;
    
    bool falling = false, falling2 = false;
    
    bool front2 = false;
    
    SDL_Surface *bg, *bg2;
    bool isRunning = true;
    
    int height = 383, width = 17;
    int height2 = 381, width2 = 0;

    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
    atexit(SDL_Quit);
    
    Mix_OpenAudio(25000, AUDIO_S16, 2, 6414);
    
    bgSound = Mix_LoadMUS("mario1.mid");
    if (bgSound == NULL)
        return 0;

    screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    if (screen == NULL)
        return 0;
        
    bg = IMG_Load("bg.bmp");
    if (bg == NULL)
        return 0;
        
    bg2 = IMG_Load("bg2.bmp");
    if (bg2 == NULL)
        return 0;
        
    SDL_Surface *mario1;
    mario1 = IMG_Load("mario1.bmp");
    if (mario1 == NULL)
        return 0;
        
    SDL_Surface *mario2;
    mario2 = IMG_Load("mario2.bmp");
    if (mario2 == NULL)
        return 0;
        
    SDL_Surface *luigi1;
    luigi1 = IMG_Load("luigi1.bmp");
    if (luigi1 == NULL)
        return 0;
        
    SDL_Surface *luigi2;
    luigi2 = IMG_Load("luigi2.bmp");
    if (luigi2 == NULL)
        return 0;
        
    bool MARIO1 = true, LUIGI1 = true, BG1 = false;
    bool LuigiJump = false, MarioJump = false;
    
    SDL_SetColorKey(mario1, SDL_SRCCOLORKEY, SDL_MapRGB(mario1->format, 0, 255, 255));
    SDL_SetColorKey(luigi1, SDL_SRCCOLORKEY, SDL_MapRGB(luigi1->format, 0, 255, 255));
    SDL_SetColorKey(mario2, SDL_SRCCOLORKEY, SDL_MapRGB(mario2->format, 0, 255, 255));
    SDL_SetColorKey(luigi2, SDL_SRCCOLORKEY, SDL_MapRGB(luigi2->format, 0, 255, 255));

    Mix_PlayMusic(bgSound, -1);

    while(isRunning)
    {
        SDL_Event event;
        SDL_PollEvent(&event);

        switch (event.type)
        {
            case SDL_QUIT:
                isRunning = false;
            break;
            case SDL_KEYDOWN:
                 switch (event.key.keysym.sym)
                 {
                     case SDLK_ESCAPE:
                         isRunning = false;
                     break;
                 }
            break;
        }
        
        keys = SDL_GetKeyState(NULL);
        
        if (keys[SDLK_UP])
        {
            MarioJump = true;
        }
        if (keys[SDLK_DOWN]);
        if (keys[SDLK_LEFT]) 
        { 
            if (width > 0)
                width -= 5;
                
            MARIO1 = false;
        }
        if (keys[SDLK_RIGHT]) 
        { 
            if (width < 780 && width > 770)
            {    
                if (BG1 == true)
                    BG1 = false;
                else
                    BG1 = true;
            }
            if (width < 780)
                width += 5;
                
            MARIO1 = true;
        }
        
        if (keys[SDLK_KP8]) 
        { 
            LuigiJump = true;
        }
        if (keys[SDLK_KP5]);
        if (keys[SDLK_KP4]) 
        { 
            if (width2 > 0)
                width2 -= 4;
                
            LUIGI1 = false;
        }
        if (keys[SDLK_KP6]) 
        { 
            if (width2 < 780 && width2 > 770)
            {    
                if (BG1 == true)
                    BG1 = false;
                else
                    BG1 = true;
            }
            if (width2 < 780)
                width2 += 4;
                
            LUIGI1 = true;
        }
        
        SDL_FillRect(screen, 0, 0);
        
        if (BG1)
        {
            if (front2 == true)
            {
                height = 383; 
                width = 18;
                height2 = 381; 
                width2 = 1;
                front2 = false;
            }
            Draw(0, 0, bg);
        }
        else
        {
            if (front2 == false)
            {
                height = 383; 
                width = 18;
                height2 = 381; 
                width2 = 1;
                front2 = true;
            }
                
            Draw(0, 0, bg2);
        }
        
        if (MarioJump == false)
        {
            if (MARIO1)
                Draw(width, height, mario1);
            else
                Draw(width, height, mario2);
        }
        else
        {
            if (height > 301 && falling == false)
            {
                height -= 5;
                
                if (MARIO1)
                    Draw(width, height, mario1);
                else
                    Draw(width, height, mario2);
            }
            else
            {
                falling = true;
                if (height < 381)
                {
                    height += 5;
                    
                    if (MARIO1)
                        Draw(width, height, mario1);
                    else
                        Draw(width, height, mario2);
                }
                else
                {       
                    MarioJump = false;
                    falling = false;
                }
            }
            if (MARIO1)
                Draw(width, height, mario1);
            else
                Draw(width, height, mario2);
        }
        
        if (LuigiJump == false)
        {    
            if (LUIGI1)
                Draw(width2, height2, luigi1);
            else
                Draw(width2, height2, luigi2);
        }
        else
        {
            if (height2 > 299 && falling2 == false)
            {
                height2 -= 5;
                
                if (LUIGI1)
                    Draw(width2, height2, luigi1);
                else
                    Draw(width2, height2, luigi2);
            }
            else
            {
                falling2 = true;
                if (height2 < 381)
                {
                    height2 += 5;
                    
                    if (LUIGI1)
                        Draw(width2, height2, luigi1);
                    else
                        Draw(width2, height2, luigi2);
                }   
                else
                {
                    LuigiJump = false;
                    falling2 = false;
                }
            }
            if (LUIGI1)
                Draw(width2, height2, luigi1);
            else
                Draw(width2, height2, luigi2);
        }
        
        SDL_Flip(screen);
    }
    
    SDL_FreeSurface(bg);
    SDL_FreeSurface(mario1);
    SDL_FreeSurface(luigi1);
    SDL_FreeSurface(mario2);
    SDL_FreeSurface(luigi2);


    Mix_FreeMusic(bgSound);
    Mix_CloseAudio();
    return 0;
}

void Draw(int x, int y, SDL_Surface *sprite)
{
    SDL_Rect source;
    SDL_Rect dest;

    source.x = 0;
    source.y = 0;
    source.w = sprite->w;
    source.h = sprite->h;

    dest.x = x;
    dest.y = y;
    dest.w = source.w;
    dest.h = source.h;

    SDL_BlitSurface(sprite, &source, screen, &dest);

    return;
}

Ints really not a problem, its just annoying to see the charactes move up and down very fast. FYI, the images are all 17x28 images, the backgrounds are 800x600. Thanks.

Share this post


Link to post
Share on other sites
Advertisement
I didn't see any Timers in there. That would explain the variation in speed from machine to machine. It looks like your trying to adjust their speed by just how far they move per cycle. Try using something like

long start = GetTickCount();


if(GetTickCount() - start >= 30)
{

// Your code here;

}


Adjust to your liking. Include <windows.h> for that Function.

Share this post


Link to post
Share on other sites
Easy way is add the following line at the end of your main loop:
while ((SDL_GetTicks() - start) < 33);
And at the beging of the main loop:
start=SDL_GetTicks();

And then fps will never be over 33 (it might be under 33 if computer is too slow).

Share this post


Link to post
Share on other sites
You could try something like this:
float startTime = (float)GetTickCount();
/* do stuff */
float endTime = (float)GetTickCount();

float frameRate = 1000.0f / ( endTime - startTime );

And then scale movement by 1.0f / frameRate.

It may also be necessary to limit the frame rate, as GetTickCount isn't too accurate. Something like
while ( frameEnd - frameStart < 10 ) {
frameEnd = (float)GetTickCount();
}

straight after the declaration of frameEnd would work.

You may need to average the value of frameRate over a few frames, and may also like to look into high precision timers (there's a lot on GameDev about these). I usually use the QueryPerformanceCounter function, but I think GetTickCount would work adequately.

Share this post


Link to post
Share on other sites
The SDL_gfx library has some framerate functions to do what you want:

"The framerate functions are used to insert delays into the graphics loop to maintain a constant framerate."

Look it up! If you dont want to do it yourself.

Good luck. :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!