键盘输入多个玩家的问题

时间:2013-12-30 06:03:39

标签: c++ class input sdl game-development

我正在为我的PONG克隆中的拨片做动作,程序有时不想注册SDL_KEYUP / DOWN。我想我已经知道为什么会这样,但现在如何解决它。因此,我的游戏循环方式目前我在main()函数中使用状态机,该函数使用Game类状态管理两个拨片和一个球,所有这些都是三个不同的类实例。在我的Game类中,我从所有三个类中运行事件/逻辑/渲染,如此

void Game::events()
{
    while (SDL_PollEvent(&event))
    {
        PlayerOne.events();
        PlayerTwo.events();
        Game_Ball.events();
    }
}

void Game::logic()
{
    PlayerOne.logic(delta.get_ticks());
    PlayerTwo.logic(delta.get_ticks());
    Game_Ball.logic();
}

void Game::render()
{
    SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0, 0, 0));
    PlayerOne.render();
    PlayerTwo.render();
    Game_Ball.render();
}

paddle班级运动就像这样管理(在上一个问题中修正了(:

void Paddle::events()
{
        Uint8 *keystates = SDL_GetKeyState(NULL);
        if (event.type == SDL_KEYDOWN)
        {
            if (player == 1)
            {
                if (keystates[SDLK_o] == 1)
                {
                    yVel -= 100;
                }
                if (keystates[SDLK_k] == 1)
                {
                    yVel += 100;
                }
            }
            else
            {
                if (keystates[SDLK_w] == 1)
                {
                    yVel -= 100;
                }
                if (keystates[SDLK_s] == 1)
                {
                    yVel += 100;
                }
            }
        }
        if (event.type == SDL_KEYUP)
        {
            if (player == 1)
            {
                if (keystates[SDLK_o] == 0)
                {
                    yVel += 100;
                }
                if (keystates[SDLK_k] == 0)
                {
                    yVel -= 100;
                }
            }
            else
            {
                if (keystates[SDLK_w] == 0)
                {
                    yVel += 100;
                }
                if (keystates[SDLK_s] == 0)
                {
                    yVel -= 100;
                }
            }
        }
        if (event.type == SDL_QUIT)
        {
            quit = true;
        }
}

这里的问题是,有时候,如果不是大部分时间,按键不会对播放器拨片上下移动做出反应。但是当他们这样做时,不到一半的时间。我认为这是因为当一个键被释放或按下时,程序只有1/3的机会轮询,有时导致位置没有变化。基本上,如果PLAYERONE在Game正在运行PlayerTwo.events()时遇到某个键,则它不会注册按键/释放键。这可能是我在我的主函数中实现游戏循环的方式的问题吗?

int main(int argc, char* args[])
{
    //init SDL
    if (init() == false)
    {
        return 1;
    }
    //load everything
    if (load_files() == false)
    {
        return 1;
    }
    delta.start();
    currentState = new Game;
    while (quit == false)
    {
        //handle state events
        currentState->events();
        // do state logic
        currentState->logic();
        //timer reset
        delta.start();
        //change state if needed
        change_state();
        //render state 
        currentState->render();
        if (SDL_Flip(screen) == -1)
        {
            return 1;
        }
    }
    clean_up();
    return 0;
}

以下是定义和构造函数

class Paddle
{
public:
    int player;
    SDL_Surface *sprite = NULL;
    float x, y, w, h;
    float yVel;
    SDL_Rect *clip;
    void events();
    void logic(Uint32 deltaTicks);
    void render();
    Paddle();
    ~Paddle();
};

class Game : public GameState
{
private:
    int server;
    TTF_Font *score = NULL;
    Paddle PlayerOne;
    Paddle PlayerTwo;
    Ball Game_Ball;
public:
    SDL_Rect clip[2];
    void events();
    void logic();
    void render();
    Game();
    ~Game();
};

Game::Game()
{
    //RESOURSES
    PlayerOne.sprite = load_image("Game_sprite.png");
    PlayerTwo.sprite = load_image("Game_sprite.png");
    clip[0].x = 0;
    clip[0].y = 0;
    clip[0].w = 20;
    clip[0].h = 20;
    clip[1].x = 0;
    clip[1].y = 20;
    clip[1].w = 20;
    clip[1].h = 100;
    //PLAYER ONE
    PlayerOne.x = 420;
    PlayerOne.y = 100;
    PlayerOne.w = 60;
    PlayerOne.h = 100;
    PlayerOne.clip = &clip[1];
    PlayerOne.yVel = 0;
    PlayerOne.player = 1;
    //PLAYER TWO
    PlayerTwo.x = 60;
    PlayerTwo.y = 100;
    PlayerTwo.w = 60;
    PlayerTwo.h = 100;
    PlayerTwo.clip = &clip[1];
    PlayerTwo.yVel = 0;
    PlayerTwo.player = 2;
    //BALL
    Game_Ball.Ball_Bound.x = 190;
    Game_Ball.Ball_Bound.y = 190;
    Game_Ball.Ball_Bound.w = 60;
    Game_Ball.Ball_Bound.h = 60;
    Game_Ball.clip = &clip[0];
}

因为这看起来很干净。除了另一个游戏循环实现之外,我可以做些什么来修复由于处于不同功能而未注册的密钥?或者它是一个循环实现问题?如果是循环问题,您是否可以通过或包含有关如何修复它的参考?

1 个答案:

答案 0 :(得分:-1)

我在这段代码中没有看到任何错误。但是,可能的原因可能仅仅是限制键盘上按下了多少键。尝试使用 shift ctrl alt ,用于控件的键,它们通常会绕过限制。