简体   繁体   中英

Clunky movement on transformable objects SFML

So I am working on a game in SFML and am having a weird problem with movement. I have implemented a delta time so the movement speed is constant but I have this weird issue where I press a move key, the object jumps by speed units, pauses, then proceeds to move smoothly. I haven't been able to find much on this as I don't really know what problems I should be looking for. Here is a copy of my current code.

#include <SFML/Graphics.hpp>
#include "Player.h"
#include <iostream>
#include <vector>

void handleKeyPress(sf::Event &event, Player &player, float dt);

int main() {

    sf::ContextSettings settings;

    settings.antialiasingLevel = 16;

    sf::RenderWindow window(sf::VideoMode(800, 600), "Title", sf::Style::Default, settings);

    sf::Event event;

    Player player;

    player.setPosition(100, 100);

    sf::Clock dtClock;

    while (window.isOpen()) {

        

        float dt = dtClock.getElapsedTime().asSeconds();
    
        while (window.pollEvent(event)) {
        
            if (event.type == sf::Event::Closed) {
    
                window.close();
    
            }

            handleKeyPress(event, player, dt);
    
            window.clear(sf::Color::Black);

            //drawing happens hear

            window.draw(player);

            //end of frame
            window.display();

            dtClock.restart();

        }
    }
}

void handleKeyPress(sf::Event& event, Player& player, float dt) {

    sf::Vector2f moveVector(0.0f, 0.0f);

    if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
        moveVector.x = -player.speed;
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
        moveVector.x = player.speed;
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
        moveVector.y = -player.speed;
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
        moveVector.y = player.speed;

    player.move(moveVector * dt);
}

Note that player is just an SFML Transformable object/drawable object.

Your main is mixing event processing and state updates with drawing, which makes it hard to respect the fractional updates you intend to do with dt . The code below undoes that: it first eats all events, then updates the game state, then draws.

In order to have smooth movement, you need to remember the Player velocity depending on which keys are pressed/released:

  • Add a velocity vector to Player
  • Change handleKeyPress to modify the velocity appropriately. Pay attention to multiple keypresses, eg up + right = (+1, +1)
  • Add an update method to player that adds a dt fraction of velocity to position.

Change it to:

while (window.isOpen()) {

    float dt = dtClock.getElapsedTime().asSeconds();

    // process events
    while (window.pollEvent(event)) {
        if (event.type == sf::Event::Closed) {
            window.close();
        } else if (event.type == sf::Event::KeyPressed || event.type == sf::Event::KeyReleased) {
            // rewrite this to update player.velocity depending on what key is pressed if released
            handleKeyPress(event, player, dt);
        }
    }

    // apply dt * player.velocity to player.position
    player.update(dt);

    // draw
    window.clear(sf::Color::Black);
    //drawing happens hear
    window.draw(player);

    // restart the dtclock here, as display() will pause for a bit
    dtClock.restart();

    //end of frame
    window.display();
}

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