Hi, I'm building a SFML and c++ Galaga clone. I've created a Player class that represents the ship and I've implemented the basic mechanics of movement and shooting. But I have a problem, I can't shoot and move the ship at the same time. What is the best way to solve it? Thank you.
Combinations of keys (SFML and c++)
Here's the code, thank you.
void Batalla::HandleInput() {
sf::Event event;
while (this->m_data->m_window.pollEvent(event)) {
if (sf::Event::Closed == event.type || sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) {
this->m_data->m_window.close();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
m_PlayerIsMoving = true;
m_playerDirection = -1;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) {
m_isFiring = true;
}
} else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
m_PlayerIsMoving = true;
m_playerDirection = 1;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) {
m_isFiring = true;
}
} else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) {
m_isFiring = true;
}
}
}
There are a couple of problems here.
You're mixing up events and real-time input. When you're using events you should be calling for states like so:
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Up) {
// Do Stuff
player.keyUpPressed(true);
}
Normally in the above case you're not handling logic, but usually setting a boolean or some form of an indication that the above action was completed, such as Keyboard Up being pressed. (You can do this in many ways, such as just setting a boolean for KeyUpPressed to true, ect... This is just a basic example of not running logic within your events section.)
The other approach is to use real-time input In your 'logic' code, such as:
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
// Move Sprite Up
player.moveUp();
}
Or if you're using the events:
if (player.keyUpPressedStatus()) {
// Move Sprite Up
player.moveUp();
player.keyUpPressed(false);
}
The problem with your code:
1. You're using real-time input in the wrong place. Never mix real-time and events.
2. Your real-time input is using 'else if' so that means it's impossible to allow more than one action to happen at a time. If you change it to 'if' you will allow more than one key check to be done at the same time allowing movement in all directions, and shooting.
Interestingly his code would actually work(well, once.. sans key repeat) if not for the fact he isn't comparing the type of the event he polled with the desired keydown state. Instead he's asking for the keystate from SFML. Obviously asking for the state will always return at least one button as being down if either one is, thus stopping the if/else chain, whereas if it was actually compared to the event then the spacebar event would show up uniquely.
The whole thing is a series of unfortunate events combining to make it not work at all.