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

Author Topic: Using sf::Keyboard::isKeyPressed in a class - InputManager help!  (Read 8060 times)

0 Members and 2 Guests are viewing this topic.

vcjr

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
So I have stumbled into a minor blockade again fallowing an old tutorial that I have managed to slowly convert into 2.1.
The problem here is that since window.GetInput() is no Longer Usable since that function is from SFML 1.6, I found that the new way to do things in 2.1 is different. I'll post the sample of code in case someone in the future is fallowing the CodingMade Easy Platformer tutorials.


SFML 1.6
InputManager.h
#ifndef INPUTMANAGER_H
#define INPUTMANAGER_H

#include <vector>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
class InputManager
{
public:
        InputManager();
        ~InputManager();

        void Update(sf::Event event);

        bool KeyPressed(int key);
        bool KeyPressed(std::vector<int> keys);

        bool KeyReleased(int key);
        bool KeyReleased(std::vector<int> keys);

        bool KeyDown(sf::RenderWindow &Window,int key);
        bool KeyDown(sf::RenderWindow &Window, std::vector<int> keys);
private:
        sf::Event event;
};

#endif
InputManager.cpp
#include "InputManager.h"


InputManager::InputManager()
{
}


InputManager::~InputManager()
{
}

void InputManager::Update(sf::Event event)
{
        this->event = event;
}

bool InputManager::KeyPressed(int key)
{
        if (event.Key.Code == key)
                return true;
}

bool InputManager::KeyPressed(std::vector<int> keys)
{
        for (int i = 0; i < keys.size(); i++)
        {
                if (event.Key.Code == keys[i])
                        return true;
        }
        return false;
}

bool InputManager::KeyReleased(int key)
{
        if (event.Key.Code == key && sf::Event::KeyReleased)
                return true;
        return false;
}

bool InputManager::KeyReleased(std::vector<int> keys)
{
        for (int i = 0; i < keys.size(); i++)
        {
                if (event.Key.Code == keys[i] && sf::Event::KeyReleased)
                        return true;
        }
        return false;
}

bool InputManager::KeyDown(sf::RenderWindow &Window, int key)
{
        if (Window.GetInput().IsKeyDown(key))
                return true;
        return false;

}

bool InputManager::KeyDown(sf::RenderWindow &Window, std::vector<int> keys)
{
        for (int i = 0; i < keys.size(); i++)
        {
                if (Window.GetInput().isKeyDown(keys[i]))
                        return true;
        }
        return false;
}
 

You can Notice the difference Since in 1.6 you have to put "event.Key.Code" in capitals while in 2.1 is lower case.

SFML 2.1
The Guy has alot of errors in his "C++ Sfml Platformer Made Easy Tutorial 6 - InputManager [Part 1]" tutorial but he probably covers them in part 2.

The really problem that I'm trying to solve is How would I implement "sf::Keyboard::isKeyPressed"  in the header file would replacing things to this help:

        bool KeyDown(sf::Keyboard::isKeyPressed,int key);
        bool KeyDown(sf::Keyboard::isKeyPressed, std::vector<int> keys);

        //or would removing int key, and the vector help ?
 
if everything works Ill post the sfml 2.1 converted version here.
« Last Edit: January 04, 2014, 06:03:59 am by vcjr »

vcjr

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Using sf::Keyboard::isKeyPressed in a class - InputManager help!
« Reply #1 on: January 04, 2014, 06:39:47 am »
After a little more hard thinking and a hour later I think i found the solution but please correct me if this is wrong . I only assume is correct since I dint receive any compile error :D

SFML 2.1
InputManager.h
   bool KeyDown(sf::Keyboard::Key key);
   bool KeyDown(std::vector<sf::Keyboard::Key> keys);
 
and InpuManager.cpp
bool InputManager::KeyDown(sf::Keyboard::Key key)
{
        if (sf::Keyboard::isKeyPressed(key))
                return true;
        return false;

}

bool InputManager::KeyDown(std::vector<sf::Keyboard::Key> keys)
{
        for (int i = 0; i < keys.size(); i++)
        {
                if (sf::Keyboard::isKeyPressed(keys[i]))
                        return true;
        }
        return false;
}
 

So far that was my pain in the behind. Also and to explain what I did to justify if I'm actually right or not or just to explain my way of thinking on why I did it that way. Well, after 20 minutes of plundering the Docs there was only one way to implement Keyboard::isKeyPressed(Key key) <---- I didn't notice that until 20+ more minutes later before that rock hit my head, I kept doing what I showed you in the first post without any success. So the solution was that if i passed a sf::Keyboard::Key type to the function and in the cpp I utilized the magic of isKeyPressed everything would work. Sorry if my way of explaining is harsh to grasp, my c++ wording isn't at it's perfection yet.


PS. If there's a better way please tell me :D
« Last Edit: January 04, 2014, 06:48:53 am by vcjr »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Using sf::Keyboard::isKeyPressed in a class - InputManager help!
« Reply #2 on: January 04, 2014, 10:02:47 am »
Everytime somebody shows code from the CodingMadeEasy tutorial, it's just questionable (see here and here). I don't recommend to follow his tutorials, they teach very bad C++ style and wrong SFML usage.

Concrete example:
bool KeyReleased(int key);
bool KeyReleased(std::vector<int> keys);
Keys are not stored as int, but sf::Keyboard::Key. There's no need to lose type safety. Furthermore, it's unnecessary to copy the whole container, a const reference would do. Additionally, the container overload could call the simple overload to avoid code duplication.

bool InputManager::KeyReleased(int key)
{
    if (event.Key.Code == key && sf::Event::KeyReleased)
        return true;
    return false;
}
Not only is the if condition unnecessary (a direct return would also work), but here it's also plain wrong. sf::Event::KeyReleased is a constant.

InputManager::~InputManager()
{
}
Again unnecessary. See also rule of three/five.

The whole design of InputManager is flawed. It stores a single event and constantly overrides it. The idea of such abstractions is to separate input handling and game logic, which is exactly not possible in the case here, because one needs to update and poll InputManager for every single event -- in the end, you have a lot of boilerplate code that simplifies nothing.

I honestly don't think it's worth to fix his codes or port them to SFML 2.1, since they're fundamentally broken. You should rather have a look at the tutorials of people who know how to program in C++. For example, those of SuperV1234 are very nice.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

vcjr

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Using sf::Keyboard::isKeyPressed in a class - InputManager help!
« Reply #3 on: January 04, 2014, 05:35:09 pm »
Thanks for the reply, the only reason I was fallowing his tutorial was to see how I would implement a way to manage everything separately for example to have : an Inputmanager, contentmanager, and even a player class to the current little game I have where its a top down shooter. The code that I have is all over the place and in Main.cpp, I want to see how I would organize  it better you know so the code could actually look like it was done for a game not a cake of things everywhere.

amir ramezani

  • Jr. Member
  • **
  • Posts: 81
  • i'm a programmer who can't see well
    • View Profile
    • download useful software!
    • Email
Re: Using sf::Keyboard::isKeyPressed in a class - InputManager help!
« Reply #4 on: January 04, 2014, 06:09:12 pm »
the best tutorial is the SFML's tutorial
read it first and enjoy
if you can't see well, you can't test your applications and operating system well
my game engine:
allegro game creator
my operating system:
AmirOS

vcjr

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Using sf::Keyboard::isKeyPressed in a class - InputManager help!
« Reply #5 on: January 04, 2014, 06:22:31 pm »
the ones where?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Using sf::Keyboard::isKeyPressed in a class - InputManager help!
« Reply #6 on: January 04, 2014, 06:39:26 pm »
[...] to see how I would implement a way to manage everything separately for example to have : an Inputmanager, contentmanager, and even a player class to the current little game I have where its a top down shooter.
Since you're talking about a top-down shooter, that's exactly what we're developing in the SFML book (the e-book is very cheap at the moment). We also split the game into modular components (input, resources, game logic, sound, network, states...) and show a possible design. If you don't want to buy the book, there's still the GitHub repository where you can see all of its source code.

the ones where?
Here.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

vcjr

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Using sf::Keyboard::isKeyPressed in a class - InputManager help!
« Reply #7 on: January 04, 2014, 07:39:45 pm »
Oh , I was thinking about that book but since you clarified what it has I'll just try to buy the digital version.