我正在制作一个简单的自上而下的 2D 射击游戏,您可以在其中使用 WASD 移动并使用空间向您注视的方向射击。我可以移动和射击,但我不能同时进行。例如,如果我正在射击并开始移动,我的角色将停止射击,直到我松开并再次按下空格键,如果我随后开始朝另一个方向移动,我必须松开并再次按下空格键。
这是我的主要方法:
int main(int argc, char* args[])
{
if (!init())
{
log("Failed to initialize!\n");
}
else
{
log("Initialized SDL and SDL subsystems. \nLoading assets:\n");
if (!loadAssets())
{
printf("Failed to load assets!\n");
}
else
{
log("All assets loaded successfully.\n");
bool running = true;
SDL_Event e;
std::vector<Shot> shots;
LTimer shotTimer;
float cooldown = 250.0f;
float previousCooldown = 0.0f;
Player player;
log("Game running.\n");
shotTimer.start();
while (running)
{
while (SDL_PollEvent(&e) != 0)
{
if (e.type == SDL_QUIT)
{
log("SDL_QUIT event triggered.\n");
running = false;
}
else if (e.type == SDL_KEYDOWN)
{
switch (e.key.keysym.sym)
{
case SDLK_ESCAPE:
{
running = false;
break;
}
}
}
player.handleEvent(e);
if (SDL_GetTicks() - previousCooldown > cooldown)
{
previousCooldown = SDL_GetTicks();
shots = shoot(e, player, shots);
}
}
player.move();
for (int i = 0; i < shots.size(); i++)
{
shots[i].move();
}
/*if (shotTimer.getTicks() >= cooldown)
shotTimer.restart();*/
SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 0xff);
SDL_RenderClear(renderer);
background.render(0, 0);
for (int i = 0; i < shots.size(); i++)
{
shots[i].render();
}
player.render();
SDL_RenderPresent(renderer);
}
}
}
close();
return 0;
}
这是我的 shoot() 函数,这可能是造成这种情况的原因:
std::vector<Shot> shoot(SDL_Event& e, Player player, std::vector<Shot> shots)
{
bool shoot = false;
if (e.type = SDL_KEYDOWN && e.key.repeat == 1)
{
switch (e.key.keysym.sym)
{
case SDLK_SPACE:
{
shoot = true;
break;
}
}
}
else if (e.type = SDL_KEYUP && e.key.repeat == 1)
{
switch (e.key.keysym.sym)
{
case SDLK_SPACE:
{
shoot = false;
break;
}
}
}
if (shoot)
{
Shot newShot(player.getDir(), player);
shots.push_back(newShot);
}
return shots;
}
这就是我移动播放器的方式
void Player::handleEvent(SDL_Event& e)
{
if (e.type == SDL_KEYDOWN && e.key.repeat == 0)
{
switch (e.key.keysym.sym)
{
case SDLK_w: mVelY -= PLAYER_VEL; mDir = 0; break;
case SDLK_s: mVelY += PLAYER_VEL; mDir = 1; break;
case SDLK_d: mVelX += PLAYER_VEL; mDir = 2; break;
case SDLK_a: mVelX -= PLAYER_VEL; mDir = 3; break;
}
}
else if (e.type == SDL_KEYUP && e.key.repeat == 0)
{
switch (e.key.keysym.sym)
{
case SDLK_w: mVelY += PLAYER_VEL; break;
case SDLK_s: mVelY -= PLAYER_VEL; break;
case SDLK_d: mVelX -= PLAYER_VEL; break;
case SDLK_a: mVelX += PLAYER_VEL; break;
}
}
}
最佳答案
将您的事件轮询与其余的游戏逻辑分开。
在单独的函数中每帧一次轮询所有事件,并将键状态的状态存储到数组中。然后,当您需要状态时,只需检查数组即可。
关于c++ - 在 SDL 中同时处理多个按键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26633669/