简体   繁体   中英

C++ and SDL2 Grid movement is too fast

My grid movement is too fast. This problem is due to speed, but I can't change it. Because then the grid doesn't work.

    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;
    }

And update for player position:

void update() override {
    position.x += round(velocity.x * 32);
    position.y += round(velocity.y * 32);
}

Problem is in update player position, but if there weren't *32 player gets out from grid. (32 is grid size)

Any idea how to solve it?

And yes, I use SDL_Delay.

If you want only one step per press then in your update() function you need to zero your velocity vector after you're done using it, that will make it step only once, but you also have to check event.key.repeat and only accept events when it's 0 to avoid repeating the event ~30 times/second as long as the key is held down. If you want the stepping to repeat after a given delay then you'll need to store the return value (a uint32_t or Uint32 if you prefer) of SDL_GetTicks(); taken the moment a SDL_KEYUP event was received (with repeats ignored) then check if enough milliseconds have passed to repeat the stepping then add the time threshold to the stored time value to properly wait for the next repeating.

Also you're zeroing your velocity vector every time any key is released, which in some cases you don't want. It might be better to add to the vector for each SDL_KEYDOWN event and subtract to under for each SDL_KEYUP, for matching keys of course. Also if you're gonna use WASD you should use scancodes instead of keysym, or your control scheme will be quite awkward on non-QWERTY layouts.

Also there's probably no need for SDL_Delay() , just use Vsync which is set when you initialise your renderer with something like renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC); .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM