C++ 和 SDL2 网格移动太快
C++ and SDL2 Grid movement is too fast
我的网格移动速度太快了。这个问题是由于速度,但我无法改变它。因为那时网格不起作用。
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 times/second 只要按住该键。如果您希望步进在给定的延迟后重复,那么您需要存储 SDL_GetTicks();
的 return 值(uint32_t
或 Uint32
,如果您愿意)收到 SDL_KEYUP 事件(忽略重复)的那一刻,然后检查是否已经过了足够的毫秒数来重复步进,然后将时间阈值添加到存储的时间值以正确等待下一次重复。
此外,每次释放任何键时,您都会将速度矢量归零,这在某些情况下是您不希望的。当然,为每个 SDL_KEYDOWN 事件添加到矢量并为每个 SDL_KEYUP 减去 under 可能更好,以匹配键。另外,如果你要使用 WASD,你应该使用扫描码而不是键符,否则你的控制方案在 non-QWERTY 布局上会很尴尬。
此外,可能不需要 SDL_Delay()
,只需使用 Vsync,它是在您使用 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
.
等初始化渲染器时设置的
我的网格移动速度太快了。这个问题是由于速度,但我无法改变它。因为那时网格不起作用。
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 times/second 只要按住该键。如果您希望步进在给定的延迟后重复,那么您需要存储 SDL_GetTicks();
的 return 值(uint32_t
或 Uint32
,如果您愿意)收到 SDL_KEYUP 事件(忽略重复)的那一刻,然后检查是否已经过了足够的毫秒数来重复步进,然后将时间阈值添加到存储的时间值以正确等待下一次重复。
此外,每次释放任何键时,您都会将速度矢量归零,这在某些情况下是您不希望的。当然,为每个 SDL_KEYDOWN 事件添加到矢量并为每个 SDL_KEYUP 减去 under 可能更好,以匹配键。另外,如果你要使用 WASD,你应该使用扫描码而不是键符,否则你的控制方案在 non-QWERTY 布局上会很尴尬。
此外,可能不需要 SDL_Delay()
,只需使用 Vsync,它是在您使用 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
.