Search code examples
c++animationconstructor2dsfml

(SFML)Player constructor not updating with correct animation when key is pressed


My sprite moves to the left, right, up and down when the correct corresponding key is pressed but only the row 0 animation is used, but for some odd reason when I press two keys at the same time like (W,A) or (S, D) is transfer to opposite animation to which side it is moving. I tried moving the if statements directing the animation update to a nested if statement inside the key press if statements and that did nothing good, I then tried just having it update based off the key press with no nested if statement, that also did not work... I am new to SFML so this is really hurting my head to figure this out, also I do not mind criticism, please if you see something I could be doing better in terms of sprite movement, let me know! Thanks for your help.

Below is my player class constructor

#include "Player.h"
    
    
    Player::Player(Texture* texture, Vector2u imageCount, float switchTime, float speed) :
        // initializer list from animation.cpp
        animation(texture, imageCount, switchTime) 
    {
        this->speed = speed;
        row = 0;
    
        body.setSize(Vector2f(100.0f, 150.0f));
        body.setTexture(texture);
        //sets initial position for test sprite sheet
        body.setPosition(550.0f, 900.0f);
    }
    
    Player::~Player()
    {
    }
    
    void Player::Update(float deltaTime)
    {
        Vector2f movement(0.0f, 0.0f);
    
        if (Keyboard::isKeyPressed(Keyboard::A))
        {
            //if A is pressed move to the left on the  x axis
            movement.x -= speed * deltaTime;
        }
        if (Keyboard::isKeyPressed(Keyboard::D))
        {
            //if D is pressed move to the right on the x axis
            movement.x += speed * deltaTime;
        }
        if (Keyboard::isKeyPressed(Keyboard::W))
        {
            // if W is pressed move up on the y axis
            movement.y += speed * deltaTime;
        }
        if (Keyboard::isKeyPressed(Keyboard::S))
        {
            // if S is pressed move down on the y axis
            movement.y -= speed * deltaTime;
        }
    
        if (movement.x == 0.0f || movement.y == 0.0f)//for idle animation
        {
            row = 0;//idle row for now just using walking until I get idle animation
        }
        else if(movement.x > 0.0f)
        {
            row = 1; //walking to the left animation
        }
        else if (movement.x < 0.0f )
        {
            row = 3; //walking to the right animation
        }
        else if (movement.y > 0.0f)
        {
            row = 0; // walking to stright animation
        }
        else if (movement.y < 0.0f)
        {
            row = 2;// walking back animation
        }
    
        animation.Update(row, deltaTime);
        body.setTextureRect(animation.uvRect);
        body.move(movement);
    
    }
    void Player::Draw(RenderWindow& window)
    {
        window.draw(body);
    }

Below is my player class initialization

#pragma once
#include <SFML/Graphics.hpp>
#include "Animation.h"
using namespace std;
using namespace sf;

class Player
{
public:
    Player(Texture* texture, Vector2u imageCount, float switchTime, float speed);
    ~Player();

    void Update(float deltaTime);
    void Draw(RenderWindow& window);

private:
    RectangleShape body;
    Animation animation;
    unsigned int row;
    float speed;

};

Below Game while loop and the Player function call

    Player player(&playerTexture, Vector2u(9, 4), 0.09f, 100.0);

    //*************************************************************
    //clock & Time
    float deltaTime = 0.0f;

    Clock clock;



    while (window.isOpen())
    {

        deltaTime = clock.restart().asSeconds();

       //*********************************************************
       //Player Input

        if (Keyboard::isKeyPressed(Keyboard::Escape))
        {
            window.close();
        }



       //**********************************************************
       //draws everything

        player.Update(deltaTime);

        window.clear();
        window.draw(spritestartingBG);
        player.Draw(window);
        window.display();
    }

    return 0;
}

Solution

  • if (movement.x == 0.0f || movement.y == 0.0f) will be true unless moving diagonally-- you probably want the || to be &&.

    Similarly, your left/right animations are reversed--you're moving left when movement.x is < 0.0, not > 0.0.