我的网格运动太快。这个问题是由于速度造成的,但我无法更改。因为那样网格将无法正常工作。

    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事件(忽略重复)后立即存储返回值(如果愿意,可以使用uint32_tUint32)。 ),然后检查是否经过了足够的毫秒数以重复步进,然后将时间阈值添加到存储的时间值中以正确等待下一次重复。

此外,每次释放任何键时,您都将速度矢量清零,这在某些情况下是不希望的。对于每个SDL_KEYDOWN事件,最好将其添加到向量中,而对于每个SDL_KEYUP,将其减去以下,以匹配密钥。同样,如果您要使用WASD,则应使用扫描代码而不是keyym,否则您的控制方案在非QWERTY布局上会很尴尬。

同样,可能也不需要SDL_GetTicks();,只需使用Vsync,当使用SDL_Delay()之类的渲染器初始化渲染器时就可以设置该Vsync。

09-25 22:19