SDL开发Pong游戏移动速度受鼠标移动影响,如何禁用鼠标检测解决该问题
问题核心原因
你当前把键盘状态读取、玩家位移更新的逻辑写在了SDL_PollEvent的内部循环中,移动鼠标时系统会持续触发大量SDL_MOUSEMOTION事件,导致内部事件轮询循环每帧执行多次,玩家位置也就被重复更新了多次,最终表现就是元素移动速度异常变快。
修复方案
1. 重构核心循环逻辑(必须修改)
将玩家输入检测、位移更新的代码从事件轮询循环中移出,事件循环仅处理必要的窗口事件即可,调整后核心循环代码如下:
while (enable_loop) { Ticks = SDL_GetTicks(); // 事件循环仅处理窗口退出类事件 while (SDL_PollEvent(&any_event)) { if (any_event.type == SDL_QUIT) { enable_loop = false; } } // 键盘状态读取、玩家更新逻辑移到事件循环外,每帧仅执行一次 keyPressed = SDL_GetKeyboardState(NULL); if (keyPressed[SDL_SCANCODE_ESCAPE]) { enable_loop = false; } if (keyPressed[SDL_SCANCODE_UP] ) { player2.Update(25); } if (keyPressed[SDL_SCANCODE_DOWN]) { player2.Update(-25); } if (keyPressed[SDL_SCANCODE_W]) { player1.Update(20); } if (keyPressed[SDL_SCANCODE_S]) { player1.Update(-20); } Grouping.update(surface, background); SDL_UpdateWindowSurface(window); limitFPS(Ticks); }
2. 可选:过滤所有鼠标事件
因为你不需要鼠标功能,可以直接注册事件过滤器丢弃所有鼠标相关事件,避免多余事件占用资源:
- 首先定义事件过滤函数
int filter_mouse_events(void *userdata, SDL_Event *event) { // 匹配所有鼠标相关事件,直接丢弃 if (event->type == SDL_MOUSEMOTION || event->type == SDL_MOUSEBUTTONDOWN || event->type == SDL_MOUSEBUTTONUP || event->type == SDL_MOUSEWHEEL) { return 0; } return 1; }
- 在SDL初始化完成后调用注册函数即可
SDL_SetEventFilter(filter_mouse_events, NULL);
3. 进阶优化:用增量时间控制移动速度
如果希望彻底规避帧率波动带来的速度变化,可以用帧间隔时间计算位移,替换原来的固定位移数值:
// 循环外保存上一帧时间 uint32_t last_tick = SDL_GetTicks(); while (enable_loop) { uint32_t current_tick = SDL_GetTicks(); // 计算两帧间隔时间,单位为秒 float delta = (current_tick - last_tick) / 1000.0f; last_tick = current_tick; // ... 省略其他逻辑 // 例:设置玩家2每秒移动250像素,替换原来的固定25值 if (keyPressed[SDL_SCANCODE_UP] ) { player2.Update(250 * delta); } // ... 其余玩家移动逻辑同理调整数值即可 }
内容的提问来源于stack exchange,提问作者Amirul Akmal
相关产品推荐
相关产品推荐

