-
I have created an inputmanager class which handles all the input in my game. What I have done is set EnableKeyRepeat to false so that it helps for single key presses. Anyways it works fine until you try to check for input using the arrow keys.
Whenever I do input using the arrow keys it treats it as continuous input but when I use other key codes it treats it as a single key press :/. Here's my inputmanager code
InputManager.h
#ifndef INPUTMANAGER_H
#define INPUTMANAGER_H
#include<vector>
#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, sf::Key::Code key);
bool KeyDown(sf::RenderWindow &Window, std::vector<sf::Key::Code> keys);
protected:
private:
sf::Event event;
};
#endif // INPUTMANAGER_H
InputManager.cpp
#include "InputManager.h"
InputManager::InputManager()
{
//ctor
}
InputManager::~InputManager()
{
//dtor
}
void InputManager::Update(sf::Event event)
{
this->event = event;
}
bool InputManager::KeyPressed(int key)
{
if(event.Key.Code == key && event.Type == sf::Event::KeyPressed)
return true;
return false;
}
bool InputManager::KeyPressed(std::vector<int> keys)
{
for(int i = 0; i < keys.size(); i++)
{
if(KeyPressed(keys[i]))
return true;
}
return false;
}
bool InputManager::KeyReleased(int key)
{
if(event.Key.Code == key && event.Type == sf::Event::KeyReleased)
return true;
return false;
}
bool InputManager::KeyReleased(std::vector<int> keys)
{
for(int i = 0; i < keys.size(); i++)
{
if(KeyReleased(keys[i]))
return true;
}
return false;
}
bool InputManager::KeyDown(sf::RenderWindow &Window, sf::Key::Code key)
{
if(Window.GetInput().IsKeyDown(key))
return true;
return false;
}
bool InputManager::KeyDown(sf::RenderWindow &Window, std::vector<sf::Key::Code> keys)
{
for(int i = 0; i < keys.size(); i++)
{
if(Window.GetInput().IsKeyDown(keys[i]))
return true;
}
return false;
}
Thanks in advance :)
-
Can the error be reproduced with a simple code (a main with an event loop), without your classes on top of it?
What's your OS?
-
I will try that right now and I'm using Windows 7. Also if you must know. I'm using sfml 1.6
-
Ok I figured out the problem but I don't know how to fix it. Ok well my input manager is not running in the event loop. When I run this code in the event loop it runs fine
if(event.Type == sf::Event::KeyPressed && event.Key.Code == sf::Key::Up)
std::cout << "UP" << std::endl;
When I run it outside of the event loop that's when things go wrong but the weird thing is that if you change sf::Key::Up to sf::Key::W then it works fine even if it's outside the event loop : /
-
Can you show how you use your input manager?
-
Sorry for the late reply but I have the code at home. But the inputmanager is essentially used like this
(dummycode.h)
#include "InputManager.h"
class Dummy
{
public:
void LoadContent();
void UnloadContent();
void Update(sf::RenderWindow &Window, sf::Event event);
void Draw(sf::RenderWindow);
private:
InputManager input;
};
(dummycode.cpp)
#include "dummycode.h"
void DummyCode::LoadContent()
{
}
void DummyCode::UnloadContent()
{
}
void DummyCode::Update(sf::RenderWindow &Window, sf::Event event)
{
input.Update(event);
if(input.KeyPressed(sf::Key::Up))
// do something
}
void DummyCode::Draw(sf::RenderWindow &Window)
{
}
(main.cpp)
#include "dummycode.h"
int main()
{
// all the initialize stuff
DummyCode dummyCode;
dummyCode.LoadContent();
while(Window.IsOpened())
{
sf::Event event;
while(Window.GetEvent(event))
{
// do the event loop actions
}
dummyCode.Update(Window, event);
dummyCode.Draw(Window);
Window.Display();
}
}
-
You use the event outside the event loop, i.e. when its value is undefined. The event is valid only within the event loop, after GetEvent returns true.
-
Yea i understand that but why does it work for all keys except for the arrow keys when I use it outside the event loop?
-
The behaviour is undefined, so anything can happen and there's no point trying to understand what happens ;)
-
So if poll returns false the event struct has been altered and might be in undefined state?
-
So if poll returns false the event struct has been altered and might be in undefined state?
Nop. If pollEvent returns false, the sf::Event instance is left untouched, which means that it's either uninitialized or filled with the previous event.
-
So using even outside event loop is/should be ok if we made sure it has been filled properly at least once before, right?
while(1)
{
sf::Event eve;
bool oka=false;
while(app.pollEvent(eve))
{
oka=true;
//whatever
}
if(oka)
{
//using event here
}
}
-
Yes. But where do you go with that? The standard (and only) way to use SFML events is an event loop which looks like this:
sf::Event event;
while (window.pollEvent(event)) // GetEvent in SFML 1.6
{
// process event
}
-
Erm.. :D
Only thing I can think of is displaying last caught event in some debugger interface without overhead of reupdating bilion times for each key, text and mouse stroke. ;D And(maybe) the ops problem, to protect against using uninitialized event struct. :P
-
The ops problem is that he's processing the event outside the event loop. No need to go further and make this simple issue confusing for him ;)