我的网格移动太快了。这个问题是由于速度造成的,但我无法改变它。因为那样网格就不工作了。
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。
如果你每次按一下只想要一个步骤,那么在你的update()
函数中,你需要在你完成使用它后将你的速度矢量归零,这将使它只步进一次,但你还必须检查event.key.repeat
并且只在它为 0 时才接受事件,以避免重复事件 ~30 次/秒只要按住键。如果您希望步进在给定延迟后重复,则需要存储收到SDL_KEYUP事件时所SDL_GetTicks();
的返回值(如果您愿意,可以uint32_t
或Uint32
)(忽略重复),然后检查是否经过了足够的毫秒来重复步进,然后将时间阈值添加到存储的时间值中以正确等待下一次重复。
此外,每次释放任何键时,您都会将速度矢量归零,在某些情况下您不希望这样做。最好为每个SDL_KEYDOWN事件添加到向量中,并为每个SDL_KEYUP减去 under,当然是为了匹配键。此外,如果你打算使用WASD,你应该使用扫描码而不是keysym,否则你的控制方案在非QWERTY布局上会非常尴尬。
也不需要SDL_Delay()
,只需使用Vsync,这是在您使用类似renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
初始化渲染器时设置的。