SFML community forums

Help => Graphics => Topic started by: Sarbast on June 26, 2014, 02:14:04 pm

Title: SFML Game Development, Movement
Post by: Sarbast on June 26, 2014, 02:14:04 pm
Hi
i wrote the code same as the book but the after the key is released the bool variables won't reset to false
and object moves without stopping
also the object moves opposite direction, when i press W set the mPlayer.move(0,-1) but it moves to down

Main.cpp

#ifdef SFML_STATIC
#pragma comment(lib, "glew.lib")
#pragma comment(lib, "freetype.lib")
#pragma comment(lib, "jpeg.lib")
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "gdi32.lib")  
#endif // SFML_STATIC

#include "game.h"
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>

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

        return 0;
}

game.h

#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>

#ifndef GAME_H
#define GAME_H

class Game{
private:
        void processEvents();
        void update();
        void render();

private:
        sf::RenderWindow mWindow;
        sf::CircleShape mPlayer;
        bool mIsMovingUp, mIsMovingDown, mIsMovingLeft, mIsMovingRight;

public:
        Game();
        void HandlePlayerInput(sf::Keyboard::Key, bool);
        void run();
};


#endif // GAME_H

game.cpp

#include "game.h"

Game::Game() : mWindow(sf::VideoMode(640, 480), "SFML Application"), mPlayer(){
        mPlayer.setRadius(40.f);
        mPlayer.setPosition(100.f, 100.f);
        mPlayer.setFillColor(sf::Color::Cyan);
}


void Game::run(){
        while (mWindow.isOpen()){
                processEvents();
                update();
                render();
        }
}

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

void Game::HandlePlayerInput(sf::Keyboard::Key key, bool isPressed){
        if (key == sf::Keyboard::W)
                mIsMovingUp = isPressed;
        else if (key == sf::Keyboard::S)
                mIsMovingDown = isPressed;
        else if (key == sf::Keyboard::A)
                mIsMovingLeft = isPressed;
        else if (key == sf::Keyboard::D)
                mIsMovingRight = isPressed;
}

void Game::update(){
        sf::Vector2f movement(0.f, 0.f);

        if (mIsMovingUp)
                movement.y -= 1.f;
        if (mIsMovingDown)
                movement.y += 1.f;
        if (mIsMovingLeft)
                movement.x -= 1.f;
        if (mIsMovingRight)
                movement.x += 1.f;

        mPlayer.move(movement);
}

void Game::render(){
       
        mWindow.clear();
        mWindow.draw(mPlayer);
        mWindow.display();
}
Title: Re: SFML Game Development, Movement
Post by: Jesper Juhl on June 26, 2014, 08:31:30 pm
Main.cpp

#ifdef SFML_STATIC
#pragma comment(lib, "glew.lib")
#pragma comment(lib, "freetype.lib")
#pragma comment(lib, "jpeg.lib")
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "gdi32.lib")  
#endif // SFML_STATIC
 

This is (IMO) a bad idea/habit.
Information about what libs to link against is platform specific and belongs in your build system (SCons, CMake, QMake, make or similar), not in your source files. You are needlessly tying your source to Windows and a specific compiler that understands those (non-standard) pragma's. There is no good reason to do that.
Title: Re: SFML Game Development, Movement
Post by: Sarbast on June 27, 2014, 02:56:46 pm
Thats the only i could make SFML static works for me
Title: Re: SFML Game Development, Movement
Post by: eXpl0it3r on June 27, 2014, 03:05:36 pm
What about adding them to the project settings next to the SFML libraries? ::)
Title: Re: SFML Game Development, Movement
Post by: Sarbast on June 27, 2014, 11:18:34 pm
I'll add them later.
nobody answered my question  :o
Title: AW: SFML Game Development, Movement
Post by: eXpl0it3r on June 27, 2014, 11:32:01 pm
You didn't provide a minimal example. ;)

Try isolating the issue further by cutting out bits that don't affect the problem. And don't forget, the debugger is your best friend.
Title: Re: SFML Game Development, Movement
Post by: Jesper Juhl on June 27, 2014, 11:35:21 pm
You never initialize your bools in your constructor, so they start out with undefined/random values.

Do this:
Game::Game() : mWindow(sf::VideoMode(640, 480), "SFML Application"), mPlayer(),
               mIsMovingUp(false), mIsMovingDown(false), mIsMovingLeft(false), mIsMovingRight(false)
 
and your code runs as I believe you expect it to :)

Edit: By the way, why are your include guards in "game.h" below the includes?
Title: Re: SFML Game Development, Movement
Post by: zsbzsb on June 29, 2014, 07:45:49 pm
Edit: By the way, why are your include guards in "game.h" below the includes?

That makes no difference....  :P
Title: Re: SFML Game Development, Movement
Post by: Peteck on June 30, 2014, 09:02:32 am
That makes no difference....  :P
For this code/project it may not do any difference. But the includes should be inside the guards.
Title: Re: SFML Game Development, Movement
Post by: janszy on July 25, 2014, 01:36:44 pm
It would be more straightforward if you put your keyboard handling directly into update function instead passing bools around. Something like this:

void Game::update(){
    sf::Vector2f movement(0.f, 0.f);

    if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
        movement.y -= 1.f;
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
        movement.y += 1.f;
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
        movement.x -= 1.f;
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
        movement.x += 1.f;

    mPlayer.move(movement);
}
 

Is this working for you? (I didn't test it)
This solution should work as long you want to move your objects while a key is pressed.
Title: Re: SFML Game Development, Movement
Post by: Peteck on July 28, 2014, 01:39:18 pm
It would be more straightforward if you put your keyboard handling directly into update function instead passing bools around. Something like this:
Well it depends on what you're trying to accomplish with your code. I normally have alot of instances of a character-class which also is the class the client should control. So when I'm doing that, all the booleans becomes extremely useful!