PlayingState.hxx 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #pragma once
  2. #ifndef SNAKE_PLAYINGSTATE_HXX
  3. #define SNAKE_PLAYINGSTATE_HXX
  4. #include "GameState.hxx"
  5. #include "AssetManager.hxx"
  6. #include <deque>
  7. #include <optional>
  8. #include <random>
  9. #include <unordered_set>
  10. namespace std {
  11. template<>
  12. struct hash<SDL_Point> {
  13. std::size_t operator()(SDL_Point const& p) const noexcept
  14. {
  15. static_assert(sizeof(std::size_t)==8u);
  16. static_assert(sizeof(int)==4u);
  17. return (static_cast<std::size_t>(p.x) << 32u) | static_cast<std::size_t>(p.y);
  18. }
  19. };
  20. }
  21. enum class Direction {
  22. Up,
  23. Right,
  24. Down,
  25. Left,
  26. };
  27. class PlayingState final : public GameState {
  28. public:
  29. static int constexpr CELLS_X = 64;
  30. static int constexpr CELLS_Y = 48;
  31. static float constexpr ACCELERATION = 1.05f;
  32. static float constexpr MAX_DISTANCE = 1.0f; // one cell per cycle
  33. static float constexpr START_SPEED = 0.005f; // 5 cell per second
  34. static float constexpr MAX_SPEED = 0.01f; // 20 cells per second
  35. PlayingState();
  36. void on_enter(GameStateManager& gsm) override;
  37. void on_event(GameStateManager& gsm, SDL_Event const& evt) override;
  38. void update(GameStateManager& gsm, std::chrono::milliseconds delta_time) override;
  39. void render(SDLRenderer& renderer) override;
  40. void render_game(SDLRenderer& renderer, bool is_current_state = true);
  41. private:
  42. void place_head();
  43. bool place_target();
  44. void render_ui(SDLRenderer& renderer, SDL_Rect const& playing_field);
  45. void render_target(SDLRenderer& renderer, SDL_Rect const& playing_field);
  46. void render_snake(SDLRenderer& renderer, SDL_Rect const& playing_field);
  47. bool detect_death(SDL_Point const& position);
  48. void handle_direction_change();
  49. std::mt19937 generator_;
  50. std::uniform_int_distribution<int> distribution_position_x_{0, CELLS_X-1};
  51. std::uniform_int_distribution<int> distribution_position_y_{0, CELLS_Y-1};
  52. std::discrete_distribution<int> distribution_deadly_wall{{5, 95}};
  53. std::discrete_distribution<std::size_t> distribution_num_targets{{0, 90, 9, 1}};
  54. std::unordered_set<SDL_Point> target_{};
  55. unsigned length_{0u};
  56. Direction direction_{Direction::Left};
  57. std::optional<Direction> new_direction_{};
  58. SDL_FPoint head_{};
  59. std::deque<SDL_Point> tail_;
  60. float speed_{0.001f};
  61. int fps_{0};
  62. bool deadly_wall_{true};
  63. Asset<TTF_Font*> font_;
  64. };
  65. #endif // SNAKE_PLAYINGSTATE_HXX