KeyDown / KeyPressed / KeyRepeated / KeyReleased 四种查询模式,覆盖持续按住、首次按下、重复触发、释放检测。
XGE 键盘输入提供四种查询语义:
• KeyDown:当前帧按键处于按下状态(持续)
• KeyPressed:本帧刚按下(仅触发一次)
• KeyRepeated:系统重复触发(如长按输入字符)
• KeyReleased:本帧刚释放
按键码使用 XGE_KEY_* 枚举(与平台无关)。
| 函数 | 说明 |
|---|---|
int xgeKeyDown(int iKey) | 按键是否按下(持续) |
int xgeKeyPressed(int iKey) | 本帧是否刚按下 |
int xgeKeyRepeated(int iKey) | 是否重复触发 |
int xgeKeyReleased(int iKey) | 本帧是否刚释放 |
void xgeInputConsumeKey(int iKey) | 消费按键(阻止传递) |
int xgeInputKeyConsumed(int iKey) | 查询是否已被消费 |
gcc -O2 -I. -o ch115.exe ch115_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch115.exe
void onFrame(void) {
float speed = 200.0f * xgeGetDelta();
// 持续按住:WASD 移动
if (xgeKeyDown('A'))
player.x -= speed;
if (xgeKeyDown('D'))
player.x += speed;
if (xgeKeyDown('W'))
player.y -= speed;
if (xgeKeyDown('S'))
player.y += speed;
// 首次按下:空格跳跃(不重复触发)
if (xgeKeyPressed(XGE_KEY_SPACE)) {
player.vy = -400.0f;
}
// 释放检测:松开 Shift 停止加速
if (xgeKeyReleased(XGE_KEY_LEFT_SHIFT)) {
player.sprinting = 0;
}
// Esc 退出
if (xgeKeyPressed(XGE_KEY_ESCAPE)) {
xgeQuit();
}
}将以下代码保存为 ch115_main.c,编译后运行即可看到键盘控制角色移动效果:
#include "xge.h"
static xge_font g_font = NULL;
static float g_px = 400.0f, g_py = 300.0f;
static float g_vy = 0.0f;
static int g_grounded = 1;
static int g_sprinting = 0;
static int onFrame(void* pUser) {
(void)pUser;
float dt = xgeGetDelta();
float speed = g_sprinting ? 400.0f : 200.0f;
// WASD 持续移动
if (xgeKeyDown('A')) g_px -= speed * dt;
if (xgeKeyDown('D')) g_px += speed * dt;
if (xgeKeyDown('W')) g_py -= speed * dt;
if (xgeKeyDown('S')) g_py += speed * dt;
// Shift 加速
g_sprinting = xgeKeyDown(XGE_KEY_LEFT_SHIFT);
// 空格跳跃(仅触发一次)
if (xgeKeyPressed(XGE_KEY_SPACE) && g_grounded) {
g_vy = -350.0f;
g_grounded = 0;
}
// 简单重力
g_vy += 800.0f * dt;
g_py += g_vy * dt;
if (g_py > 500.0f) {
g_py = 500.0f;
g_vy = 0;
g_grounded = 1;
}
// Esc 退出
if (xgeKeyPressed(XGE_KEY_ESCAPE))
xgeQuit();
// 绘制
xgeClear(0x081114FF);
xgeShapeRectFill((xge_rect_t){0,520,800,80}, 0x224422FF);
xgeShapeRectFill(
(xge_rect_t){g_px-15, g_py-30, 30, 30},
g_sprinting ? 0xFFB454FF : 0x4FD8C2FF);
char buf[128];
sprintf(buf, "WASD:move Shift:sprint Space:jump Esc:quit");
xgeTextDraw(g_font, buf, 50, 30, 0xFFFFFFFF);
return XGE_OK;
}
int main(void) {
xge_desc_t d = {0};
d.iWidth = 800;
d.iHeight = 600;
d.sTitle = "ch115 - Keyboard";
d.iFlags = XGE_INIT_VSYNC;
xgeInit(&d);
g_font = xgeFontLoad("res/font/default.ttf", 24);
xgeRun(onFrame, NULL);
xgeFontFree(g_font);
xgeUnit();
return 0;
}权威源码为 examples/tutorial_capture/ch115_main1.c。它通过公开的 xgeInputEventPost 回放 KEY_DOWN 与 KEY_UP,再以 xgeInputEventGet 顺序消费并断言最终动作状态已释放。游戏代码应将这些事件映射到自己的 action 状态,而不是把平台按键散落在玩法逻辑中。
