You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SDL2主游戏循环外的Scene类中正确获取键盘输入?

问题原因

你的主循环中事件处理顺序完全错误:你先调用sceneManager.Update(&event),此时event还未被SDL_PollEvent填充有效事件数据,之后才去处理事件队列。场景类拿到的event要么是上一帧的残留数据,要么是未初始化的无效值,自然无法检测到按键输入。

解决方案

方案1:调整主循环顺序,传递所有事件给场景

修改主循环逻辑,先处理事件队列,将每个事件传递给场景管理器/场景:

while (running)
{
    window.Clear();
    window.SetColor(23, 23, 23, 255);

    SDL_Event event;
    // 先遍历所有事件,逐个传递给场景处理
    while (SDL_PollEvent(&event))
    {
        if (event.type == SDL_QUIT)
        {
            running = false;
        }
        // 将事件传递给场景管理器,再分发给当前场景
        sceneManager.HandleEvent(&event);
    }

    // 事件处理完成后,执行场景逻辑更新
    sceneManager.Update();
    window.Display();
}

对应的Scene类需要新增事件处理方法:

// Scene.h 声明
class LoadingScene : public Scene {
public:
    void HandleEvent(SDL_Event* event);
    void Update();
};

// Scene.cpp 实现
void LoadingScene::HandleEvent(SDL_Event* event)
{
    if (event->type == SDL_KEYDOWN) 
    {
        cout << "Keydown" << endl;
    }
}

void LoadingScene::Update()
{
    rain.Update();
    text.Update();
}

方案2:直接获取键盘状态(适合持续按键检测)

如果不需要检测单次按键的按下/释放事件,而是要判断某一帧内按键是否处于按下状态,可使用SDL_GetKeyboardState,无需传递SDL_Event:

void LoadingScene::Update()
{
    rain.Update();
    text.Update();

    // 获取当前键盘状态数组
    const Uint8* keyboardState = SDL_GetKeyboardState(nullptr);
    // 检测指定按键,例如空格键
    if (keyboardState[SDL_SCANCODE_SPACE])
    {
        cout << "Space key is held down" << endl;
    }
}

这种方式无需修改主循环事件逻辑,适合角色移动等需要持续检测按键状态的场景。

补充说明
  • 方案1适用于处理一次性事件(如按键按下/释放、鼠标点击、窗口关闭),每个事件只会被处理一次。
  • 方案2适用于处理持续输入状态,每一帧都能检测按键是否被按住。

内容的提问来源于stack exchange,提问作者Kesh S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 05:35:35