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
相关产品推荐
相关产品推荐

