Pārlūkot izejas kodu

:recycle: switched to more direct keyboard handling in the game

Felix Bytow 1 gadu atpakaļ
vecāks
revīzija
ce3bf85d94
2 mainītis faili ar 30 papildinājumiem un 34 dzēšanām
  1. 28 34
      game/PlayingState.cxx
  2. 2 0
      game/PlayingState.hxx

+ 28 - 34
game/PlayingState.cxx

@@ -59,44 +59,12 @@ void PlayingState::on_event(GameStateManager& gsm, SDL_Event const& evt)
     if (scancode==SDL_SCANCODE_ESCAPE || scancode==SDL_SCANCODE_PAUSE)
       gsm.push_state(GameStates::MainMenu);
   }
-  else if (evt.type==SDL_KEYDOWN) {
-    switch (evt.key.keysym.scancode) {
-    default:
-      break;
-    case SDL_SCANCODE_UP:
-      [[fallthrough]];
-    case SDL_SCANCODE_W:
-      if (direction_==Direction::Left || direction_==Direction::Right) {
-        new_direction_ = Direction::Up;
-      }
-      break;
-    case SDL_SCANCODE_S:
-      [[fallthrough]];
-    case SDL_SCANCODE_DOWN:
-      if (direction_==Direction::Left || direction_==Direction::Right) {
-        new_direction_ = Direction::Down;
-      }
-      break;
-    case SDL_SCANCODE_A:
-      [[fallthrough]];
-    case SDL_SCANCODE_LEFT:
-      if (direction_==Direction::Up || direction_==Direction::Down) {
-        new_direction_ = Direction::Left;
-      }
-      break;
-    case SDL_SCANCODE_D:
-      [[fallthrough]];
-    case SDL_SCANCODE_RIGHT:
-      if (direction_==Direction::Up || direction_==Direction::Down) {
-        new_direction_ = Direction::Right;
-      }
-      break;
-    }
-  }
 }
 
 void PlayingState::update(GameStateManager& gsm, std::chrono::milliseconds const delta_time)
 {
+  handle_direction_change();
+
   auto const distance = speed_*static_cast<float>(delta_time.count());
   if (distance>MAX_DISTANCE) {
     SDL_Log("Snake would move a distance of %f. Game might have been stuck. Skipping cycle.", distance);
@@ -147,6 +115,32 @@ void PlayingState::update(GameStateManager& gsm, std::chrono::milliseconds const
   head_ = new_head;
 }
 
+void PlayingState::handle_direction_change()
+{
+  // this is not done in the event handler as we don't want to wait for KEYUP to re-fire in certain situations
+  auto const keyboard = SDL_GetKeyboardState(nullptr);
+  if (keyboard[SDL_SCANCODE_UP] || keyboard[SDL_SCANCODE_W]) {
+    if (direction_==Direction::Left || direction_==Direction::Right) {
+      new_direction_ = Direction::Up;
+    }
+  }
+  else if (keyboard[SDL_SCANCODE_DOWN] || keyboard[SDL_SCANCODE_S]) {
+    if (direction_==Direction::Left || direction_==Direction::Right) {
+      new_direction_ = Direction::Down;
+    }
+  }
+  else if (keyboard[SDL_SCANCODE_LEFT] || keyboard[SDL_SCANCODE_A]) {
+    if (direction_==Direction::Up || direction_==Direction::Down) {
+      new_direction_ = Direction::Left;
+    }
+  }
+  else if (keyboard[SDL_SCANCODE_RIGHT] || keyboard[SDL_SCANCODE_D]) {
+    if (direction_==Direction::Up || direction_==Direction::Down) {
+      new_direction_ = Direction::Right;
+    }
+  }
+}
+
 void PlayingState::render(SDLRenderer& renderer)
 {
   render_game(renderer);

+ 2 - 0
game/PlayingState.hxx

@@ -52,6 +52,8 @@ private:
 
   bool detect_death(SDL_Point const& position);
 
+  void handle_direction_change();
+
   std::default_random_engine generator_;
   std::uniform_int_distribution<int> distribution_position_x_{0, CELLS_X-1};
   std::uniform_int_distribution<int> distribution_position_y_{0, CELLS_Y-1};