Question

I am creating a pong clone in C++ using SDL. The Paddles are ready and move according to the user input. What keeps worrying me is that the input is weird, I expected smooth movement of both the paddles but one paddle lags when the other paddle is moving and speeds up when the other is not moving. I doubt if this is caused by not capping FPS or by the weird way that I managed to get multiple input or both. Can anyone tell me what is wrong in my code and how to improve it?

My code:

#include <SDL/SDL.h>
#include <string>
#include "SDL/SDL_image.h"
#include <SDL/SDL_ttf.h>

bool quit = false;
bool keyheld[323]={false};
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
const int SCREEN_BPP = 32;
int paddle1x = 0;
int paddle1y = 50;
int paddle2x = 600;
int paddle2y = 500;

SDL_Color color = {255,255,255};
SDL_Event event;
SDL_Surface* screen = NULL;
SDL_Surface* timer = NULL;
SDL_Surface* background = NULL;
SDL_Surface* paddle1 =NULL;
SDL_Surface* paddle2 = NULL;

void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination)
{
    SDL_Rect offset;
    offset.x = x;
    offset.y = y;
    SDL_BlitSurface(source, NULL,destination, &offset);
}

 SDL_Surface *load_image(std::string filename)
    {
        SDL_Surface* loadedimage = NULL;
        SDL_Surface* optimisedimage = NULL;

        loadedimage= IMG_Load(filename.c_str());
        optimisedimage= SDL_DisplayFormatAlpha(loadedimage);
        SDL_FreeSurface(loadedimage);

        return optimisedimage;
    }

int main(int argc, char *args[])
{
    bool quit = false;
    bool keyheld[323]={false};
    int p1score=0;
    int p2score=0;

    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();
    TTF_Font *font=NULL;

    screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE);

    background = load_image("background.png");
    apply_surface(0,0,background,screen);

    paddle1 = load_image("paddle1.png");
    apply_surface(paddle1x,paddle1y,paddle1,screen);

    paddle2=load_image("paddle2.png");
    apply_surface(paddle2x,paddle2y,paddle2,screen);


    font = TTF_OpenFont("kremlin.ttf", 22);

    timer = TTF_RenderText_Solid(font,"Test!",color);
    apply_surface(0,0,timer,screen);

    SDL_WM_SetCaption("PONG!",NULL);
    SDL_Flip(screen);
    while(quit==false)
    {
            if(SDL_PollEvent(&event))
            {
                SDLKey keyPressed = event.key.keysym.sym;
                if(event.type==SDL_QUIT)
                {
                    return 0;
                }
                else if(event.type==SDL_KEYDOWN)
                {
                    keyheld[keyPressed] = true;
                }
                else if(event.type==SDL_KEYUP)
                {
                    keyheld[keyPressed] = false;
                }



            }
            if(keyheld[SDLK_LEFT])
            {
                paddle1x--;
                apply_surface(0,0,background,screen);
                apply_surface(paddle1x,paddle1y,paddle1,screen);
                apply_surface(paddle2x,paddle2y,paddle2,screen);
            }
            if(keyheld[SDLK_RIGHT])
            {
                paddle1x++;
                apply_surface(0,0,background,screen);
                apply_surface(paddle1x,paddle1y,paddle1,screen);
                apply_surface(paddle2x,paddle2y,paddle2,screen);
            }
            if(keyheld[SDLK_a])
                {
                paddle2x--;
                apply_surface(0,0,background,screen);
                apply_surface(paddle1x,paddle1y,paddle1,screen);
                apply_surface(paddle2x,paddle2y,paddle2,screen);
                }
                if(keyheld[SDLK_d])
                {
                paddle2x++;
                apply_surface(0,0,background,screen);
                apply_surface(paddle1x,paddle1y,paddle1,screen);
                apply_surface(paddle2x,paddle2y,paddle2,screen);
                }

            apply_surface(0,0,timer,screen);
            SDL_Flip(screen);
            SDL_Delay(2);
    }

    return 0;
}
Was it helpful?

Solution

The problem is because you update the backbuffer for every type of paddle move. If both paddles move you end up updating it twice. This is where you are encountering the slowdown. You should only be updating the backbuffer once every frame. Like so:

if(keyheld[SDLK_LEFT])
{
    paddle1x--;
}
if(keyheld[SDLK_RIGHT])
{
    paddle1x++;
}
if(keyheld[SDLK_a])
{
    paddle2x--;
}
if(keyheld[SDLK_d])
{
    paddle2x++;
}

// Now we do the update. You can always add a flag to see if the update
// really needs to be done and skip it if it doesn't
apply_surface(0,0,background,screen);
apply_surface(paddle1x,paddle1y,paddle1,screen);
apply_surface(paddle2x,paddle2y,paddle2,screen);

apply_surface(0,0,timer,screen);
SDL_Flip(screen);
SDL_Delay(2);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top