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

Author Topic: Shape not moving  (Read 3053 times)

0 Members and 1 Guest are viewing this topic.

sb8623

  • Newbie
  • *
  • Posts: 4
    • View Profile
Shape not moving
« on: March 27, 2020, 09:12:06 pm »
Started learning SFML. Got hands on this piece of code.
Code: [Select]
#include<SFML/Window.hpp>
#include<SFML/Graphics.hpp>


class Game{
public:
    Game();
    void run(); //to call in the main function
private:
    void process_events(); //for user input
    void update(); //actual code
    void render(); //render after creating
   
   
    void handle_player_input(sf::Keyboard::Key, bool);
   
private:
    sf::RenderWindow m_window;
    sf::CircleShape m_player;
   
    bool is_moving_up;
    bool is_moving_down;
    bool is_moving_left;
    bool is_moving_right;
};

Game::Game()
: m_window(sf::VideoMode(640, 480), "SFML App", sf::Style::Default)
, m_player(){
    m_player.setRadius(40.f);
    m_player.setPosition(100.f, 100.f);
    m_player.setFillColor(sf::Color::Cyan);
}

void Game::run(){
    while(m_window.isOpen()){
        process_events();
        update();
        render();
    }
}

void Game::handle_player_input(sf::Keyboard::Key key, bool is_pressed){
    if(key == sf::Keyboard::W){
        is_moving_up = is_pressed;
    }
    else if(key == sf::Keyboard::S){
        is_moving_down = is_pressed;
    }
    else if(key == sf::Keyboard::A){
        is_moving_left = is_pressed;
    }
    else if(key == sf::Keyboard::D){
        is_moving_right = is_pressed;
    }
}


void Game::process_events(){
    sf::Event event;
    while(m_window.pollEvent(event)){
        sf::Event event;
        switch(event.type){
            case sf::Event::KeyPressed:
                handle_player_input(event.key.code, true);
                break;
            case sf::Event::KeyReleased:
                handle_player_input(event.key.code, false);
                break;
            case sf::Event::Closed:
                m_window.close();
                break;
        }
    }
}

void Game::update(){
    sf::Vector2f movement(0.f, 0.f);
    if(is_moving_up)
        movement.y -= 1.f;
    if(is_moving_down)
        movement.x += 1.f;
    if(is_moving_left)
        movement.x -= 1.f;
    if(is_moving_right)
        movement.x += 1.f;
   
    m_player.move(movement);
}

void Game::render(){
    m_window.clear(sf::Color::Black);
    m_window.draw(m_player);
    m_window.display();
}


int main(){
    Game game;
    game.run();
}

I thought why bother about the boolean variable in handle_player_input() and changed the function to:
Code: [Select]
void Game::handle_player_input(){
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
        m_player.move(0.f, 1.f);
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
        m_player.move(0.f, -1.f);
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
        m_player.move(-1.f, 0.f);
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
        m_player.move(1.f, 0.f);
}
But for both cases the shape is not moving though I am getting the cyan circle.
Edit1: I am using ArchLinux.(if that helps)
Edit2: changed {up, down, left, right} to {W, A, S. D} in first program(to match the second). Tested the program in a different linux distribution. Same result.
The event of closing the window also gets disabled when I run the program with the handle_user_input() function. I need to Ctrl+c to exit.
« Last Edit: March 27, 2020, 10:22:54 pm by sb8623 »

G.

  • Hero Member
  • *****
  • Posts: 1590
    • View Profile
Re: Shape not moving
« Reply #1 on: March 27, 2020, 10:28:52 pm »
while(m_window.pollEvent(event)) fills the event, don't declare a new one the line after. ;)
(it should issue at least a warning?)

sb8623

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Shape not moving
« Reply #2 on: March 27, 2020, 10:40:30 pm »
Oh! Thanks. It wasn't deliberate. I didn't get any warning though

sb8623

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Shape not moving
« Reply #3 on: March 27, 2020, 10:51:33 pm »
I compiled the two programs(after correcting) and they behave very differently. In the one with the bool variable to store the state, the shape disappears when tried to move. In the second program(which uses isKeyPressed()) the circle moves smoothly. Why is there a difference of behavior?
« Last Edit: March 27, 2020, 11:12:24 pm by sb8623 »

nogoodname

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Shape not moving
« Reply #4 on: April 10, 2020, 03:19:35 am »
Oh! Thanks. It wasn't deliberate. I didn't get any warning though

If you're using GCC, you can enable the warning with -Wshadow.

I compiled the two programs(after correcting) and they behave very differently. In the one with the bool variable to store the state, the shape disappears when tried to move. In the second program(which uses isKeyPressed()) the circle moves smoothly. Why is there a difference of behavior?


It's because you're invoking undefined behaviour.

void Game::update(){
    sf::Vector2f movement(0.f, 0.f);
    if(is_moving_up)
        movement.y -= 1.f;
    if(is_moving_down)
        movement.x += 1.f;
    if(is_moving_left)
        movement.x -= 1.f;
    if(is_moving_right)
        movement.x += 1.f;
   
    m_player.move(movement);
}
 

In this function there's no guarantee that is_moving_up, is_moving_down, is_moving_left, is_moving_right have been initialised yet, so this function will act unexpectedly.

Please note that a boolean member variable are not initialised by default, so you have to make sure it's initialised. You can do it in the constructor or the class definition.

sb8623

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Shape not moving
« Reply #5 on: April 10, 2020, 08:19:20 am »
Quote
If you're using GCC, you can enable the warning with -Wshadow.
Thanks. Will keep that in mind.

Quote
In this function there's no guarantee that is_moving_up, is_moving_down, is_moving_left, is_moving_right have been initialised yet, so this function will act unexpectedly.
Yes . Thank you. As this was somewhat a late reply, I figured that out.  ;D