Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Jittery Movement Even With deltaTime  (Read 3581 times)

0 Members and 1 Guest are viewing this topic.

MrSnappingTurtle

  • Newbie
  • *
  • Posts: 21
    • View Profile
    • Email
Jittery Movement Even With deltaTime
« on: May 30, 2014, 04:49:01 am »
Hi,

I was creating the code to move my sprite and implemented deltaTime into it, yet the sprite still jitters often when moving around. Does anyone know what is wrong? Comment if you need more detail.

main.cpp
#include <SFML/Graphics.hpp>
#include "player.h"

int main()
{
        sf::RenderWindow window(sf::VideoMode(1280, 720), "Incremental");

        sf::Clock clock;
        player player;

        //Game Loop
        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
                }

                window.clear();
                player.update(clock.restart().asSeconds());
                window.draw(player.sprite);
                window.display();
                clock.restart();
        }

        return 0;
}

player.h
#ifndef PLAYER_H
#define PLAYER_H
#include <SFML/Graphics.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/System/Time.hpp>
#include <SFML/Window/Keyboard.hpp>


class player
{
private:

        // Clock and timer used to iterate between positions on the sprite sheet.
        sf::Clock fpsClock;
        sf::Time fpsTimer;

        sf::Texture spriteSheet;


        //Animation States
        enum AnimationState
        {
                idle,
                run,
                interact
        };

        AnimationState animationState = idle;
       
        //Used to check if sprite scale is already inversed when going left.
        bool spriteInvertable = true;
        //Movement
        sf::Vector2f position;
        float speed = 10000;

        //Scale Properties
        float spriteScaleX = 10, spriteScaleY = 10;

        /*Animation positions in the sprite sheet...
        Arrays are static and initialized elsewhere
        cause VS is a POS and I had to use a workaround.
        */

        const sf::IntRect IDLE = sf::IntRect(0, 0, 8, 10);
        static const sf::IntRect RUN[2];
        static const sf::IntRect INTERACT[4];

public:

        sf::Sprite sprite;
       
        //Animation Functions
        void setAnimationState(const AnimationState&);
        void animate();
        void update(const double&);

        player();
};

#endif
 

player.cpp
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/Rect.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/System/Time.hpp>
#include <SFML/Window/Keyboard.hpp>
#include <iostream>
#include "player.h"

const sf::IntRect player::RUN[2] =
{
        sf::IntRect(33, 0, 8, 10),
        sf::IntRect(44, 0, 8, 10)
};
const sf::IntRect player::INTERACT[4] =
{
        sf::IntRect(1, 0, 8, 10),
        sf::IntRect(9, 0, 8, 10),
        sf::IntRect(17, 0, 8, 10),
        sf::IntRect(9, 0, 8, 10)
};

void player::setAnimationState(const AnimationState& state)
{
        animationState = state;
}
void player::update(const double& deltaTime)
{
        //Debugz
        std::cout << deltaTime << std::endl;

        //Movement Update
        if
                (
                sf::Keyboard::isKeyPressed(sf::Keyboard::D) &&
                !sf::Keyboard::isKeyPressed(sf::Keyboard::A) &&
                animationState != interact
                )
        {
                //Moves the sprite
                sprite.move(speed * deltaTime, 0);

                setAnimationState(run);
                fpsTimer = fpsClock.getElapsedTime();

                //Animates by going through the texture (probably a better way to do this...)
                if (fpsTimer.asMilliseconds() <= 30 * 3)
                {
                        sprite.setTextureRect(RUN[0]);
                }
                else if (fpsTimer.asMilliseconds() <= 60 * 3 && fpsTimer.asMilliseconds() > 30 * 3)
                {
                        sprite.setTextureRect(RUN[1]);
                }
                else if (fpsTimer.asMilliseconds() >= 60 * 3)
                {
                        fpsClock.restart();
                }

                //Re-enables spriteInvertable and uninverts the image if it was inverted.
                if (!spriteInvertable)
                {
                        sprite.setScale(spriteScaleX, spriteScaleY);
                        spriteInvertable = true;
                }
        }
        else if
                (
                sf::Keyboard::isKeyPressed(sf::Keyboard::A) &&
                !sf::Keyboard::isKeyPressed(sf::Keyboard::D) &&
                animationState != interact
                )
        {
                //Moves the sprite
                sprite.move(-1 * speed * deltaTime, 0);
               
                setAnimationState(run);
                fpsTimer = fpsClock.getElapsedTime();

                //Animates by going through the texture (probably a better way to do this...)
                if (fpsTimer.asMilliseconds() <= 30 * 3)
                {
                        sprite.setTextureRect(RUN[0]);
                }
                else if (fpsTimer.asMilliseconds() <= 60 * 3 && fpsTimer.asMilliseconds() > 30 * 3)
                {
                        sprite.setTextureRect(RUN[1]);
                }
                else if (fpsTimer.asMilliseconds() >= 60 * 3)
                {
                        fpsClock.restart();
                }
               
                //Inverts Sprite
                if (spriteInvertable)
                {
                        sprite.setScale(-spriteScaleX, spriteScaleY);
                        spriteInvertable = false;
                }

        }
        else
        {
                sprite.setTextureRect(IDLE);
        }
}

player::player()
{
        //Loads up the texture and sets the sprite to it.
        spriteSheet.loadFromFile("../art/final/player.png");
        sprite.setTexture(spriteSheet);
        sprite.setOrigin(5, 8);
        //Default state
        sprite.move(0, 100);
        sprite.setTextureRect(IDLE);
        sprite.setScale(spriteScaleX, spriteScaleY);
}

THANKS!  ;)

Geheim

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Email
Re: Jittery Movement Even With deltaTime
« Reply #1 on: May 30, 2014, 11:21:57 am »
window.clear();
player.update(clock.restart().asSeconds());
window.draw(player.sprite);
window.display();
clock.restart();

You restart the clock twice, just make a float for your deltatime and pass it:
(click to show/hide)
Failing to succeed does not mean failing to progress!

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
Re: Jittery Movement Even With deltaTime
« Reply #2 on: May 30, 2014, 11:34:26 am »
Or even better pass a sf::Time around to be more flexible.

auto deltaTime = clock.restart();
player.update(deltaTime);
 


AlexAUT

MrSnappingTurtle

  • Newbie
  • *
  • Posts: 21
    • View Profile
    • Email
Re: Jittery Movement Even With deltaTime
« Reply #3 on: May 30, 2014, 07:36:31 pm »
Thanks, that seems to have helped. I have one more question though... (new forum post because it isn't related to this; it is in the same section though).