重构键盘输入为 IKeyboardState 接口,消除 App 层对 SDL 的直接依赖
重构键盘输入为 IKeyboardState 接口,消除 App 层对 SDL 的直接依赖 - 新增 IKeyboardState 抽象接口及 SdlKeyboardState/EvdevKeyboardState 实现 - PlayerController 改用 IKeyboardState 替代直接调用 SDL_GetKeyboardState - 移除 Camera2D.h 中对 Core 私有头文件 Camera.h 的引用 - 将 Timer.h 从 Core/Core 移至 Core/Platform,符合架构边界规范 - 键盘输入优先级调整为高于指针输入
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include "Vector2.h"
|
||||
#include "Camera.h"
|
||||
#include "Level.h"
|
||||
|
||||
namespace LightGame
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "DrawContext.h"
|
||||
#include "BitmapFont.h"
|
||||
#include "ButtonInput.h"
|
||||
#include "IKeyboardState.h"
|
||||
#include "PointerInput.h"
|
||||
#include "LevelData.h"
|
||||
#include "LevelLoader.h"
|
||||
@@ -25,11 +26,13 @@ namespace LightGame
|
||||
int32_t screen_width,
|
||||
int32_t screen_height,
|
||||
Platform::IButtonInput* button_input,
|
||||
Platform::IKeyboardState* keyboard_input,
|
||||
Platform::IPointerInput* pointer_input,
|
||||
Platform::IPhotoSensor* photo_sensor)
|
||||
: screen_width_(screen_width),
|
||||
screen_height_(screen_height),
|
||||
button_input_(button_input),
|
||||
keyboard_input_(keyboard_input),
|
||||
pointer_input_(pointer_input),
|
||||
photo_sensor_(photo_sensor),
|
||||
level_(),
|
||||
@@ -146,7 +149,7 @@ namespace LightGame
|
||||
GameObject* player = level_.get_object(player_id_);
|
||||
if (player)
|
||||
{
|
||||
player_controller_.update(*player, level_, physics_, button_input_, pointer_input_, dt_ms);
|
||||
player_controller_.update(*player, level_, physics_, button_input_, keyboard_input_, pointer_input_, dt_ms);
|
||||
camera_.follow(player->position);
|
||||
|
||||
if (player_controller_.is_dead())
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace RenderData
|
||||
namespace Platform
|
||||
{
|
||||
class IButtonInput;
|
||||
class IKeyboardState;
|
||||
class IPointerInput;
|
||||
}
|
||||
|
||||
@@ -35,8 +36,10 @@ namespace LightGame
|
||||
int32_t screen_height_;
|
||||
|
||||
Platform::IButtonInput* button_input_;
|
||||
Platform::IKeyboardState* keyboard_input_;
|
||||
Platform::IPointerInput* pointer_input_;
|
||||
Platform::IPhotoSensor* photo_sensor_;
|
||||
// TODO: consolidate input interfaces into IInputState when a 4th modality arrives
|
||||
|
||||
Level level_;
|
||||
Camera2D camera_;
|
||||
@@ -56,6 +59,7 @@ namespace LightGame
|
||||
int32_t screen_width,
|
||||
int32_t screen_height,
|
||||
Platform::IButtonInput* button_input,
|
||||
Platform::IKeyboardState* keyboard_input,
|
||||
Platform::IPointerInput* pointer_input,
|
||||
Platform::IPhotoSensor* photo_sensor);
|
||||
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
#include "PlayerController.h"
|
||||
#include "ButtonInput.h"
|
||||
#include "IKeyboardState.h"
|
||||
#include "PointerInput.h"
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef USE_FRAMEBUFFER
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
namespace LightGame
|
||||
{
|
||||
PlayerController::PlayerController()
|
||||
@@ -48,6 +45,7 @@ namespace LightGame
|
||||
|
||||
void PlayerController::update(GameObject& obj, Level& level, Physics2D& physics,
|
||||
const Platform::IButtonInput* button,
|
||||
const Platform::IKeyboardState* keyboard,
|
||||
const Platform::IPointerInput* pointer,
|
||||
uint32_t dt_ms)
|
||||
{
|
||||
@@ -61,7 +59,7 @@ namespace LightGame
|
||||
return;
|
||||
}
|
||||
|
||||
update_input(button, pointer);
|
||||
update_input(button, keyboard, pointer);
|
||||
update_movement(obj, dt_ms);
|
||||
|
||||
physics.apply_gravity(obj, dt_ms);
|
||||
@@ -114,6 +112,7 @@ namespace LightGame
|
||||
}
|
||||
|
||||
void PlayerController::update_input(const Platform::IButtonInput* button,
|
||||
const Platform::IKeyboardState* keyboard,
|
||||
const Platform::IPointerInput* pointer)
|
||||
{
|
||||
move_dir_ = 0;
|
||||
@@ -147,27 +146,14 @@ namespace LightGame
|
||||
}
|
||||
}
|
||||
|
||||
if (move_dir_ == 0)
|
||||
if (keyboard)
|
||||
{
|
||||
#ifndef USE_FRAMEBUFFER
|
||||
SDL_PumpEvents();
|
||||
const Uint8* keys = SDL_GetKeyboardState(nullptr);
|
||||
if (keys)
|
||||
{
|
||||
if (keys[SDL_SCANCODE_LEFT] || keys[SDL_SCANCODE_A])
|
||||
{
|
||||
move_dir_ = -1;
|
||||
}
|
||||
if (keys[SDL_SCANCODE_RIGHT] || keys[SDL_SCANCODE_D])
|
||||
{
|
||||
move_dir_ = 1;
|
||||
}
|
||||
if (keys[SDL_SCANCODE_SPACE] || keys[SDL_SCANCODE_UP] || keys[SDL_SCANCODE_W])
|
||||
{
|
||||
jump_held_ = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (keyboard->is_key_down(Platform::KEY_LEFT) || keyboard->is_key_down(Platform::KEY_A))
|
||||
move_dir_ = -1;
|
||||
if (keyboard->is_key_down(Platform::KEY_RIGHT) || keyboard->is_key_down(Platform::KEY_D))
|
||||
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))
|
||||
jump_held_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
namespace Platform
|
||||
{
|
||||
class IButtonInput;
|
||||
class IKeyboardState;
|
||||
class IPointerInput;
|
||||
}
|
||||
|
||||
@@ -72,6 +73,7 @@ namespace LightGame
|
||||
|
||||
void update(GameObject& obj, Level& level, Physics2D& physics,
|
||||
const Platform::IButtonInput* button,
|
||||
const Platform::IKeyboardState* keyboard,
|
||||
const Platform::IPointerInput* pointer,
|
||||
uint32_t dt_ms);
|
||||
|
||||
@@ -79,7 +81,7 @@ namespace LightGame
|
||||
bool is_dead() const { return state_ == PlayerState::Dead; }
|
||||
|
||||
private:
|
||||
void update_input(const Platform::IButtonInput* button, const Platform::IPointerInput* pointer);
|
||||
void update_input(const Platform::IButtonInput* button, const Platform::IKeyboardState* keyboard, const Platform::IPointerInput* pointer);
|
||||
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);
|
||||
|
||||
@@ -53,6 +53,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
Platform::DefaultButtonInput buttonInput;
|
||||
Platform::DefaultKeyboardState keyboardState;
|
||||
Platform::DefaultPointerInput pointerInput;
|
||||
Platform::DefaultPhotoSensor photoSensor;
|
||||
|
||||
@@ -86,6 +87,7 @@ int main(int argc, char* argv[])
|
||||
ScreenWidth,
|
||||
ScreenHeight,
|
||||
&buttonInput,
|
||||
&keyboardState,
|
||||
&pointerInput,
|
||||
&photoSensor);
|
||||
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
#include "AlsaAudioInput.h"
|
||||
#include "AlsaAudioOutput.h"
|
||||
#include "EvdevButtonInput.h"
|
||||
#include "EvdevKeyboardState.h"
|
||||
#include "EvdevTouchInput.h"
|
||||
#include "LinuxPhotoSensor.h"
|
||||
#else
|
||||
#include "SdlAudioInput.h"
|
||||
#include "SdlAudioOutput.h"
|
||||
#include "SdlKeyboardButtonInput.h"
|
||||
#include "SdlKeyboardState.h"
|
||||
#include "SdlPointerInput.h"
|
||||
#include "SdlPhotoSensor.h"
|
||||
#endif
|
||||
@@ -20,12 +22,14 @@ namespace Platform
|
||||
typedef AlsaAudioInput DefaultAudioInput;
|
||||
typedef AlsaAudioOutput DefaultAudioOutput;
|
||||
typedef EvdevButtonInput DefaultButtonInput;
|
||||
typedef EvdevKeyboardState DefaultKeyboardState;
|
||||
typedef EvdevTouchInput DefaultPointerInput;
|
||||
typedef LinuxPhotoSensor DefaultPhotoSensor;
|
||||
#else
|
||||
typedef SdlAudioInput DefaultAudioInput;
|
||||
typedef SdlAudioOutput DefaultAudioOutput;
|
||||
typedef SdlKeyboardButtonInput DefaultButtonInput;
|
||||
typedef SdlKeyboardState DefaultKeyboardState;
|
||||
typedef SdlPointerInput DefaultPointerInput;
|
||||
typedef SdlPhotoSensor DefaultPhotoSensor;
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "EvdevKeyboardState.h"
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
bool EvdevKeyboardState::is_key_down(int /*scancode*/) const
|
||||
{
|
||||
// Embedded target uses physical buttons via IButtonInput, not keyboard.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "IKeyboardState.h"
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
// Embedded target uses physical buttons via IButtonInput, not keyboard.
|
||||
class EvdevKeyboardState : public IKeyboardState
|
||||
{
|
||||
public:
|
||||
bool is_key_down(int scancode) const override;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
// Key constants matching SDL scancode values.
|
||||
// App-layer code uses these instead of including <SDL.h>.
|
||||
constexpr int KEY_A = 4;
|
||||
constexpr int KEY_D = 7;
|
||||
constexpr int KEY_W = 26;
|
||||
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;
|
||||
|
||||
class IKeyboardState
|
||||
{
|
||||
public:
|
||||
virtual ~IKeyboardState() {}
|
||||
virtual bool is_key_down(int scancode) const = 0;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "SdlKeyboardState.h"
|
||||
#include <SDL.h>
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
bool SdlKeyboardState::is_key_down(int scancode) const
|
||||
{
|
||||
// Relies on SdlKeyboardButtonInput::update() having called SDL_PumpEvents() in the same frame.
|
||||
const Uint8* state = SDL_GetKeyboardState(nullptr);
|
||||
return state != nullptr && state[scancode] != 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "IKeyboardState.h"
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
class SdlKeyboardState : public IKeyboardState
|
||||
{
|
||||
public:
|
||||
// Must be called after SdlKeyboardButtonInput::update() or equivalent SDL_PumpEvents() call.
|
||||
bool is_key_down(int scancode) const override;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user