我的网格移动太快。这个问题是由于速度造成的,但我无法更改。因为那样网格将无法正常工作。
if (Game::event.type == SDL_KEYDOWN) {
if (Game::event.key.keysym.sym == SDLK_w || Game::event.key.keysym.sym == SDLK_UP) {
transform->velocity.y = -1;
}
else if (Game::event.key.keysym.sym == SDLK_s || Game::event.key.keysym.sym == SDLK_DOWN) {
transform->velocity.y = 1;
}
else if (Game::event.key.keysym.sym == SDLK_d || Game::event.key.keysym.sym == SDLK_RIGHT) {
transform->velocity.x = 1;
}
else if (Game::event.key.keysym.sym == SDLK_a || Game::event.key.keysym.sym == SDLK_LEFT) {
transform->velocity.x = -1;
}
} else if (Game::event.type == SDL_KEYUP) {
transform->velocity.x = 0;
transform->velocity.y = 0;
}
并更新玩家位置:
void update() override {
position.x += round(velocity.x * 32);
position.y += round(velocity.y * 32);
}
问题出在更新播放器位置,但是如果没有* 32播放器退出网格。 (32是网格大小)
有什么办法解决吗?
是的,我使用SDL_Delay。
答案 0 :(得分:1)
如果您希望每次按下仅一步,则在update()
函数中,您需要在使用完速度向量后将其归零,这将使其只迈出一次,但是您还必须检查{ {1}},并且仅当它为0时才接受事件,以免在按住该键的同时每秒〜30次重复该事件。如果您希望在给定的延迟后重复执行步进操作,则需要存储SDL_KEYUP事件发生后的返回值(如果愿意,可以使用event.key.repeat
的{{1}}或uint32_t
)收到(忽略重复),然后检查是否经过了足够的毫秒以重复步进,然后将时间阈值添加到存储的时间值中,以正确等待下一次重复。
此外,每次释放任何键时,您都将速度矢量清零,这在某些情况下是不希望的。对于每个SDL_KEYDOWN事件,最好将其添加到向量中,而对于每个SDL_KEYUP,将其减去以下,以匹配密钥。另外,如果您要使用WASD,则应使用扫描代码而不是keyym,否则您的控制方案在非QWERTY布局上会很尴尬。
也许也不需要Uint32
,只需使用Vsync,当您使用SDL_GetTicks();
之类的渲染器初始化渲染器时设置即可。