From acf162d1b9ad29309aca3cd2072b90b81920a3ce Mon Sep 17 00:00:00 2001 From: SepComet <2428390463@qq.com> Date: Thu, 11 Jun 2026 10:41:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20LightGame=20Windows=20?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E9=97=AE=E9=A2=98=E5=B9=B6=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E6=89=8B=E5=8A=A8=E4=BA=AE=E5=BA=A6=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构 PlayerController 输入:移除 IButtonInput 依赖,纯使用 IKeyboardState 与 IPointerInput;触摸屏改为上半屏跳跃、左右 1/3 分区分左右移动 - GameStateManager 增加 ESC 键暂停/恢复支持 - 将键盘亮度控制从 SdlPhotoSensor 平台层上提到 LightGameApp 游戏层(W/S 键),并引入 has_manual_override_ 标志防止 photo sensor 默认值覆盖手动调整 - SDLDisplay 初始化时调用 SDL_StopTextInput(),缓解 Windows 中文输入法在按字母键后拦截方向键/空格的问题 - IKeyboardState.h 补充 KEY_S、KEY_ESC、KEY_RETURN 常量 --- .../LightGame/src/engine/GameStateManager.cpp | 14 +++-- .../LightGame/src/engine/GameStateManager.h | 4 +- .../LightGame/src/engine/LightGameApp.cpp | 61 ++++++++++++++++--- src/Apps/LightGame/src/engine/LightGameApp.h | 5 ++ .../LightGame/src/engine/PlayerController.cpp | 42 ++++++------- .../LightGame/src/engine/PlayerController.h | 5 +- src/Core/Platform/IKeyboardState.h | 3 + src/Core/Platform/SDLDisplay.cpp | 1 + src/Core/Platform/SdlPhotoSensor.cpp | 42 +------------ 9 files changed, 98 insertions(+), 79 deletions(-) diff --git a/src/Apps/LightGame/src/engine/GameStateManager.cpp b/src/Apps/LightGame/src/engine/GameStateManager.cpp index 34a39d1..8c568f9 100644 --- a/src/Apps/LightGame/src/engine/GameStateManager.cpp +++ b/src/Apps/LightGame/src/engine/GameStateManager.cpp @@ -2,6 +2,7 @@ #include "DrawContext.h" #include "BitmapFont.h" #include "ButtonInput.h" +#include "IKeyboardState.h" #include namespace LightGame @@ -10,14 +11,19 @@ namespace LightGame : state_(GameState::Title), hud_(), title_blink_ms_(0), - title_show_prompt_(true) + title_show_prompt_(true), + esc_was_down_(false) { } - void GameStateManager::update(GameState current_state, const Platform::IButtonInput* button, uint32_t dt_ms) + void GameStateManager::update(GameState current_state, const Platform::IButtonInput* button, const Platform::IKeyboardState* keyboard, uint32_t dt_ms) { state_ = current_state; + const bool esc_down = keyboard && keyboard->is_key_down(Platform::KEY_ESC); + const bool esc_pressed = esc_down && !esc_was_down_; + esc_was_down_ = esc_down; + switch (state_) { case GameState::Title: @@ -30,14 +36,14 @@ namespace LightGame break; case GameState::Playing: - if (button && button->was_pressed()) + if (esc_pressed || (button && button->was_pressed())) { state_ = GameState::Paused; } break; case GameState::Paused: - if (button && button->was_pressed()) + if (esc_pressed || (button && button->was_pressed())) { state_ = GameState::Playing; } diff --git a/src/Apps/LightGame/src/engine/GameStateManager.h b/src/Apps/LightGame/src/engine/GameStateManager.h index 4d4fc22..c5b6a6e 100644 --- a/src/Apps/LightGame/src/engine/GameStateManager.h +++ b/src/Apps/LightGame/src/engine/GameStateManager.h @@ -15,6 +15,7 @@ namespace RenderData namespace Platform { class IButtonInput; + class IKeyboardState; } namespace LightGame @@ -53,11 +54,12 @@ namespace LightGame HudData hud_; uint32_t title_blink_ms_; bool title_show_prompt_; + bool esc_was_down_; public: GameStateManager(); - void update(GameState current_state, const Platform::IButtonInput* button, uint32_t dt_ms); + void update(GameState current_state, const Platform::IButtonInput* button, const Platform::IKeyboardState* keyboard, uint32_t dt_ms); void draw(Core::DrawContext& ctx, const RenderData::BitmapFont& font, int32_t screen_w, int32_t screen_h); void set_state(GameState state) { state_ = state; } diff --git a/src/Apps/LightGame/src/engine/LightGameApp.cpp b/src/Apps/LightGame/src/engine/LightGameApp.cpp index bd9f931..18b58bf 100644 --- a/src/Apps/LightGame/src/engine/LightGameApp.cpp +++ b/src/Apps/LightGame/src/engine/LightGameApp.cpp @@ -9,6 +9,7 @@ #include "Level1Data.h" #include "Level2Data.h" #include "Level3Data.h" +#include "sprite_atlas.h" namespace LightGame { @@ -44,21 +45,58 @@ namespace LightGame renderer_(), current_level_index_(0), player_id_(0), + manual_light_level_(2048), + light_step_(256), + has_manual_override_(false), debug_mode_(false) { camera_.configure(screen_width, screen_height); camera_.set_dead_zone(60, 40); + + static const RenderData::Sprite player_idle[] = { + sprite_atlas::spr_player_idle_0, + sprite_atlas::spr_player_idle_1 + }; + static const RenderData::Sprite player_run[] = { + sprite_atlas::spr_player_run_0, + sprite_atlas::spr_player_run_1, + sprite_atlas::spr_player_run_2, + sprite_atlas::spr_player_run_3 + }; + player_controller_.set_sprites( + player_idle, 2, + player_run, 4, + &sprite_atlas::spr_player_jump, + &sprite_atlas::spr_player_fall); } void LightGameApp::update(uint32_t dt_ms) { - if (photo_sensor_ && photo_sensor_->is_open()) + if (keyboard_input_) + { + if (keyboard_input_->is_key_down(Platform::KEY_W)) + { + const uint32_t next = static_cast(manual_light_level_) + light_step_; + manual_light_level_ = static_cast(next > 4095 ? 4095 : next); + has_manual_override_ = true; + } + if (keyboard_input_->is_key_down(Platform::KEY_S)) + { + manual_light_level_ = manual_light_level_ >= light_step_ + ? manual_light_level_ - light_step_ + : 0; + has_manual_override_ = true; + } + } + + if (photo_sensor_ && photo_sensor_->is_open() && !has_manual_override_) { photo_sensor_->update(); + manual_light_level_ = photo_sensor_->read_level(); } const GameState prev_state = state_manager_.get_state(); - state_manager_.update(prev_state, button_input_, dt_ms); + state_manager_.update(prev_state, button_input_, keyboard_input_, dt_ms); switch (state_manager_.get_state()) { @@ -86,7 +124,7 @@ namespace LightGame if (state_manager_.get_state() == GameState::Playing || state_manager_.get_state() == GameState::Paused) { - const uint16_t light = photo_sensor_ ? photo_sensor_->read_level() : 2048; + const uint16_t light = manual_light_level_; renderer_.draw(ctx, level_, camera_, light_system_, light); if (debug_mode_) @@ -99,7 +137,7 @@ namespace LightGame if (debug_mode_ && state_manager_.get_state() == GameState::Playing) { - const uint16_t light = photo_sensor_ ? photo_sensor_->read_level() : 2048; + const uint16_t light = manual_light_level_; char buf[32]; snprintf(buf, sizeof(buf), "L:%d", light); ctx.draw_text(font, screen_width_ - 64, screen_height_ - 16, @@ -130,10 +168,15 @@ namespace LightGame state_manager_.get_hud().current_level = level_index + 1; } + bool LightGameApp::is_action_pressed() + { + return button_input_ && button_input_->was_pressed(); + } + void LightGameApp::update_title(uint32_t dt_ms) { (void)dt_ms; - if (button_input_ && button_input_->was_pressed()) + if (is_action_pressed()) { load_level(0); state_manager_.set_state(GameState::Playing); @@ -142,14 +185,14 @@ namespace LightGame void LightGameApp::update_playing(uint32_t dt_ms) { - const uint16_t light = photo_sensor_ ? photo_sensor_->read_level() : 2048; + const uint16_t light = manual_light_level_; light_system_.update(level_.get_all_objects(), light); state_manager_.get_hud().light_level = light; GameObject* player = level_.get_object(player_id_); if (player) { - player_controller_.update(*player, level_, physics_, button_input_, keyboard_input_, pointer_input_, dt_ms); + player_controller_.update(*player, level_, physics_, keyboard_input_, pointer_input_, screen_width_, screen_height_, dt_ms); camera_.follow(player->position); if (player_controller_.is_dead()) @@ -168,7 +211,7 @@ namespace LightGame void LightGameApp::update_game_over(uint32_t dt_ms) { (void)dt_ms; - if (button_input_ && button_input_->was_pressed()) + if (is_action_pressed()) { state_manager_.get_hud().lives = 3; state_manager_.get_hud().collectibles = 0; @@ -180,7 +223,7 @@ namespace LightGame void LightGameApp::update_level_complete(uint32_t dt_ms) { (void)dt_ms; - if (button_input_ && button_input_->was_pressed()) + if (is_action_pressed()) { const int32_t next = current_level_index_ + 1; if (next < kLevelCount) diff --git a/src/Apps/LightGame/src/engine/LightGameApp.h b/src/Apps/LightGame/src/engine/LightGameApp.h index 47334eb..87c6aac 100644 --- a/src/Apps/LightGame/src/engine/LightGameApp.h +++ b/src/Apps/LightGame/src/engine/LightGameApp.h @@ -52,6 +52,10 @@ namespace LightGame int32_t current_level_index_; uint32_t player_id_; + uint16_t manual_light_level_; + uint16_t light_step_; + + bool has_manual_override_; bool debug_mode_; public: @@ -76,5 +80,6 @@ namespace LightGame void update_game_over(uint32_t dt_ms); void update_level_complete(uint32_t dt_ms); void check_triggers(); + bool is_action_pressed(); }; } diff --git a/src/Apps/LightGame/src/engine/PlayerController.cpp b/src/Apps/LightGame/src/engine/PlayerController.cpp index 7c70c1a..d27a2cd 100644 --- a/src/Apps/LightGame/src/engine/PlayerController.cpp +++ b/src/Apps/LightGame/src/engine/PlayerController.cpp @@ -1,5 +1,4 @@ #include "PlayerController.h" -#include "ButtonInput.h" #include "IKeyboardState.h" #include "PointerInput.h" #include @@ -44,9 +43,9 @@ namespace LightGame } void PlayerController::update(GameObject& obj, Level& level, Physics2D& physics, - const Platform::IButtonInput* button, const Platform::IKeyboardState* keyboard, const Platform::IPointerInput* pointer, + int32_t screen_width, int32_t screen_height, uint32_t dt_ms) { if (state_ == PlayerState::Dead) @@ -59,7 +58,7 @@ namespace LightGame return; } - update_input(button, keyboard, pointer); + update_input(keyboard, pointer, screen_width, screen_height); update_movement(obj, dt_ms); physics.apply_gravity(obj, dt_ms); @@ -111,48 +110,45 @@ namespace LightGame check_death(obj, level); } - void PlayerController::update_input(const Platform::IButtonInput* button, - const Platform::IKeyboardState* keyboard, - const Platform::IPointerInput* pointer) + void PlayerController::update_input(const Platform::IKeyboardState* keyboard, + const Platform::IPointerInput* pointer, + int32_t screen_width, int32_t screen_height) { move_dir_ = 0; jump_held_ = false; - if (button) - { - if (button->is_down()) - { - jump_held_ = true; - } - } - if (pointer) { if (pointer->is_down()) { const int32_t px = pointer->get_x(); - if (px < 400) + const int32_t py = pointer->get_y(); + + // Top half of screen = jump (works across the full width) + if (py < screen_height / 2) + { + jump_held_ = true; + } + + // Left 1/3 = move left, right 1/3 = move right + if (px < screen_width / 3) { move_dir_ = -1; } - else if (px > 600) + else if (px > screen_width * 2 / 3) { move_dir_ = 1; } - else - { - jump_held_ = true; - } } } if (keyboard) { - if (keyboard->is_key_down(Platform::KEY_LEFT) || keyboard->is_key_down(Platform::KEY_A)) + if (keyboard->is_key_down(Platform::KEY_LEFT)) move_dir_ = -1; - if (keyboard->is_key_down(Platform::KEY_RIGHT) || keyboard->is_key_down(Platform::KEY_D)) + if (keyboard->is_key_down(Platform::KEY_RIGHT)) move_dir_ = 1; - if (keyboard->is_key_down(Platform::KEY_SPACE) || keyboard->is_key_down(Platform::KEY_UP) || keyboard->is_key_down(Platform::KEY_W)) + if (keyboard->is_key_down(Platform::KEY_UP)) jump_held_ = true; } } diff --git a/src/Apps/LightGame/src/engine/PlayerController.h b/src/Apps/LightGame/src/engine/PlayerController.h index cc5d343..28abc72 100644 --- a/src/Apps/LightGame/src/engine/PlayerController.h +++ b/src/Apps/LightGame/src/engine/PlayerController.h @@ -6,7 +6,6 @@ namespace Platform { - class IButtonInput; class IKeyboardState; class IPointerInput; } @@ -72,16 +71,16 @@ namespace LightGame const RenderData::Sprite* fall); void update(GameObject& obj, Level& level, Physics2D& physics, - const Platform::IButtonInput* button, const Platform::IKeyboardState* keyboard, const Platform::IPointerInput* pointer, + int32_t screen_width, int32_t screen_height, uint32_t dt_ms); PlayerState get_state() const { return state_; } bool is_dead() const { return state_ == PlayerState::Dead; } private: - void update_input(const Platform::IButtonInput* button, const Platform::IKeyboardState* keyboard, const Platform::IPointerInput* pointer); + void update_input(const Platform::IKeyboardState* keyboard, const Platform::IPointerInput* pointer, int32_t screen_width, int32_t screen_height); void update_movement(GameObject& obj, uint32_t dt_ms); void update_animation(GameObject& obj, uint32_t dt_ms); void check_death(GameObject& obj, Level& level); diff --git a/src/Core/Platform/IKeyboardState.h b/src/Core/Platform/IKeyboardState.h index 557f5b6..aa6bb5e 100644 --- a/src/Core/Platform/IKeyboardState.h +++ b/src/Core/Platform/IKeyboardState.h @@ -7,11 +7,14 @@ namespace Platform constexpr int KEY_A = 4; constexpr int KEY_D = 7; constexpr int KEY_W = 26; + constexpr int KEY_S = 22; constexpr int KEY_SPACE = 44; constexpr int KEY_LEFT = 80; constexpr int KEY_RIGHT = 79; constexpr int KEY_UP = 82; constexpr int KEY_DOWN = 81; + constexpr int KEY_ESC = 41; + constexpr int KEY_RETURN = 40; class IKeyboardState { diff --git a/src/Core/Platform/SDLDisplay.cpp b/src/Core/Platform/SDLDisplay.cpp index 9b01d7c..76dd15a 100644 --- a/src/Core/Platform/SDLDisplay.cpp +++ b/src/Core/Platform/SDLDisplay.cpp @@ -57,6 +57,7 @@ namespace Platform return false; } + SDL_StopTextInput(); return true; } diff --git a/src/Core/Platform/SdlPhotoSensor.cpp b/src/Core/Platform/SdlPhotoSensor.cpp index 89286f3..52bfadc 100644 --- a/src/Core/Platform/SdlPhotoSensor.cpp +++ b/src/Core/Platform/SdlPhotoSensor.cpp @@ -50,45 +50,9 @@ namespace Platform void SdlPhotoSensor::update() { - if (!opened_) - { - return; - } - - SDL_PumpEvents(); - const Uint8* keyboard_state = SDL_GetKeyboardState(nullptr); - if (!keyboard_state) - { - return; - } - - if (keyboard_state[SDL_SCANCODE_UP]) - { - uint32_t next = static_cast(level_) + step_; - level_ = static_cast(std::min(next, static_cast(max_level_))); - } - - if (keyboard_state[SDL_SCANCODE_DOWN]) - { - if (level_ >= step_) - { - level_ -= step_; - } - else - { - level_ = min_level_; - } - } - - if (keyboard_state[SDL_SCANCODE_HOME]) - { - level_ = max_level_; - } - - if (keyboard_state[SDL_SCANCODE_END]) - { - level_ = min_level_; - } + // No-op: keyboard-based brightness control is handled in the game layer + // (LightGameApp) through IKeyboardState, not at the platform level. + (void)opened_; } void SdlPhotoSensor::shutdown()