我正在为我的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];
}
因为这看起来很干净。除了另一个游戏循环实现之外,我可以做些什么来修复由于处于不同功能而未注册的密钥?或者它是一个循环实现问题?如果是循环问题,您是否可以通过或包含如何解决它的参考?
我在这段代码中没有看到任何错误。但是,可能的原因可能仅仅是限制键盘上按下了多少键。尝试使用shift,ctrl和alt,键进行控制,它们通常会绕过限制。