2014-10-29 80 views
0

我正在製作一個簡單的自上而下的2D射擊遊戲,在那裏您使用WASD移動並朝空間方向進行拍攝。我可以移動並拍攝得很好,但我無法同時做到這一點。例如,如果我正在拍攝並開始移動,我的角色將停止拍攝,直到我釋放並再次按空間,然後如果我開始向另一個方向移動,我必須再次釋放並按空間。在SDL中同時處理多個keypressess

這是我的主要方法:

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

這是我拍攝()函數,這可能是什麼造成這樣的:

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

回答

3

將事件輪詢與遊戲邏輯的其餘部分分開。

輪詢所有事件一次每幀在一個單獨的函數中並將keystate的狀態存儲到一個數組中。然後,當你需要狀態時,只需檢查數組。

3

您還可以使用SDL_GetKeyboardState來取樣鍵的外鍵狀態,而無需親自處理鍵事件。

+0

此答案僅適用於SDL 2,對不對?這個問題似乎是關於SDL 1.x – Martin 2014-10-30 06:56:06

+2

SDL1.2具有'SDL_GetKeyState',它的功能基本相同。 – keltar 2014-10-30 07:40:55

+0

對,你是:) – Martin 2014-10-30 08:42:26