Управление вводом в SDL?

Я создаю клон pong на С++, используя SDL. Весла готовы и двигаются в соответствии с вводом пользователя. Что меня продолжает беспокоить, так это то, что ввод является странным, я ожидал плавного движения обоих лепестков, но один манипулятор отстает, когда другой манипулятор движется, и ускоряется, когда другой не движется. Я сомневаюсь, что это вызвано отсутствием ограничения FPS или странным способом, которым мне удалось получить несколько входных данных, или и тем, и другим. Может ли кто-нибудь сказать мне, что не так в моем коде и как его улучшить?

Мой код:

#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;
}

person Rohan Bojja    schedule 20.04.2013    source источник
comment
Я ожидал плавного движения обеих лопастей, но лопасти отстают, когда другая лопатка движется, и ускоряются, когда другая не движется. Как это решить?   -  person Rohan Bojja    schedule 20.04.2013


Ответы (1)


Проблема в том, что вы обновляете резервный буфер для каждого типа движения весла. Если оба лепестка двигаются, вы в конечном итоге обновляете его дважды. Вот где вы сталкиваетесь с замедлением. Вы должны обновлять задний буфер только один раз в каждом кадре. Вот так:

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);
person Captain Obvlious    schedule 20.04.2013