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

C++新手开发Flappy游戏:如何在Sleep函数执行时检测输入?

解决Sleep期间检测输入的问题

你当前代码里的std::cin >> answer是阻塞式输入,程序会停在这里等待用户输入,彻底打乱游戏的Tick节奏;而Sleep执行期间程序完全暂停,自然也无法检测输入。针对Windows平台,这里给你两种适合初学者的非阻塞输入解决方案:

方案一:使用_kbhit()和_getch()(快速实现)

这两个是Windows下C标准库的扩展函数,_kbhit()非阻塞检查是否有按键按下,_getch()读取按键且不回显到控制台,刚好适配游戏操作场景。

修改后的代码示例:

#include <conio.h> // 必须包含这个头文件

while (GameStarted) {
    bool hasInput = false;
    char key = 0;

    // 非阻塞检查是否有按键输入
    if (_kbhit()) {
        key = _getch();
        hasInput = true;
    }

    // 处理玩家位置逻辑
    if (hasInput) {
        // 这里以空格键作为跳跃触发键,可替换成你需要的按键(比如'w')
        if (key == ' ') {
            Player.SetPosition(Player.GetPosition().x, Player.GetPosition().y - 1);
        }
    } else {
        // 无输入时玩家自然下落
        Player.SetPosition(Player.GetPosition().x, Player.GetPosition().y + 1);
    }

    // 绘制游戏帧
    system("CLS");
    DrawFrame(Player, YPositionDrawn);
    TicksCounted++;
    std::cout << "Tick!" << TicksCounted << '\n';

    // 等待Tick时长,输入检测已在Sleep前完成,不会错过操作
    Sleep(DurationOfATick);
}

关键说明

  • _kbhit()仅做状态检查,不会暂停程序;
  • _getch()读取按键后不在控制台显示,避免干扰游戏画面;
  • 把输入检测放在Sleep之前,保证每一次Tick都优先处理用户操作,再进入等待。

方案二:使用GetAsyncKeyState()(支持特殊按键)

如果需要检测方向键、功能键这类特殊按键,可使用Windows原生APIGetAsyncKeyState(),它能实时获取按键的按下/释放状态。

示例代码:

#include <windows.h> // 你已经包含这个头文件

while (GameStarted) {
    bool isJumpPressed = false;

    // 检测空格键是否按下(VK_SPACE是空格的虚拟键码)
    if (GetAsyncKeyState(VK_SPACE) & 0x8000) {
        isJumpPressed = true;
    }

    // 位置逻辑处理
    if (isJumpPressed) {
        Player.SetPosition(Player.GetPosition().x, Player.GetPosition().y - 1);
    } else {
        Player.SetPosition(Player.GetPosition().x, Player.GetPosition().y + 1);
    }

    // 绘制与等待
    system("CLS");
    DrawFrame(Player, YPositionDrawn);
    TicksCounted++;
    std::cout << "Tick!" << TicksCounted << '\n';

    Sleep(DurationOfATick);
}

关键说明

  • 返回值与0x8000做按位与运算,结果非零则表示按键当前处于按下状态;
  • 虚拟键码可参考Windows官方定义,比如VK_UP是上方向键、VK_LEFT是左方向键;
  • 该方法支持检测持续按住按键的状态,适合需要连续操作的场景。

额外提示

  • 游戏实时输入绝对不要用std::cin,它是为文本输入设计的阻塞特性完全不匹配游戏循环;
  • system("CLS")刷新控制台可能出现闪烁,后期可尝试控制台缓冲区操作优化,但当前阶段先以实现核心功能为主;
  • 确保头文件正确引入:conio.h对应方案一的函数,windows.h对应方案二和Sleep()。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 09:50:29