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

Author Topic: [Solved] [SFML 2.1 with VS2012] Event Help - keyboard and mouse problem  (Read 5385 times)

0 Members and 1 Guest are viewing this topic.

sleeter

  • Newbie
  • *
  • Posts: 4
    • View Profile
Hello everyone,

Please let me start by explicitly stating, I am not an expert or a great programmer. I know a little (normally just enough to get myself into bother, but not out of it) and have only written a couple of simple VB programs for my work.

I tend to learn by trying bits of a program out before I put those bits together into a final project. At the moment I am working on splash screens for a game I have a mind to program but I cannot work out how to have the splash screen visible until the player presses a key (any key, rather than a specific key). I didn't want to do this by polling for every single key on the keyboard, so I'm trying to trigger on the event 'KeyReleased' (see code).

My problem is that 'KeyReleased' is triggered when I mouse-over the SFML window, which seems to be completely against what I would intuit and can see from the documentation I've read.

 :-[

main.cpp
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include "loop.h"

int main() {
        Loop::StartLoop();
}

loop.h
#pragma once

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

class Loop {

public:
        Loop() { _loopState = Dead; };
        ~Loop() { };

        static void StartLoop();
       
        static sf::RenderWindow _loopWindow;

private:
        static void ContinuousLoop();
        static void Pause();

        static enum PossibleLoopStates { Dead, Opening, Running, Closing };
        static int _loopState;
};

loop.cpp
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include "loop.h"
#include "splash.h"

void Loop::StartLoop() {
        if(_loopState == Dead) {
                _loopWindow.create(sf::VideoMode(800, 400), "Looper Window");
                Splash::ShowSplash(_loopWindow);
                _loopState = Opening;
                ContinuousLoop();
        } else {
                return;
        }
}

void Loop::ContinuousLoop() {

        while(_loopWindow.isOpen()) {
                sf::Event happened;

                _loopWindow.clear();

                while(_loopWindow.pollEvent(happened)) {
                        if(happened.type == sf::Event::Closed)
                                _loopWindow.close();
                        if(happened.type == sf::Event::KeyPressed && happened.key.code == sf::Keyboard::Escape)
                                _loopWindow.close();
                        if(happened.type == sf::Event::LostFocus) {
                                Pause();
                                std::cout << "\nUnpaused!";
                        }
                }

                _loopWindow.display();
        }
}

void Loop::Pause() {

        while(_loopWindow.isOpen()) {
                sf::Event happened;

                std::cout << "Paused!";

                sf::sleep(sf::milliseconds(500));

                while(_loopWindow.pollEvent(happened)) {
                        if(happened.type == sf::Event::Closed)
                                _loopWindow.close();
                        if(happened.type == sf::Event::KeyPressed && happened.key.code == sf::Keyboard::Escape)
                                _loopWindow.close();
                        if(happened.type == sf::Event::GainedFocus)
                                return;
                }

                _loopWindow.display();
        }
}

sf::RenderWindow Loop::_loopWindow;
int Loop::_loopState;

splash.h
#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

class Splash {

public:
        Splash() { };
        ~Splash() { };

        static void SetTexture();
        static void ShowSplash(sf::RenderWindow&);

private:
        static sf::Texture _splashTexture;
        static sf::Sprite _splashSprite;
};

splash.cpp
#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include "splash.h"
#include "loop.h"

void Splash::SetTexture() {
        if(!_splashTexture.loadFromFile("splash.png")) {
                std::cout << "Splash Texture failed to load!";
                return;
        } else {
                _splashSprite.setTexture(_splashTexture);
        }
}

void Splash::ShowSplash(sf::RenderWindow& window) {
       
        SetTexture();
       
        while(window.isOpen()) {
                sf::Event happened;

                window.clear();

                while(window.pollEvent(happened)) {
                        if(happened.type == sf::Event::Closed)
                                window.close();
                        if(happened.type == sf::Event::KeyPressed && happened.key.code == sf::Keyboard::Escape)
                                window.close();
                        if(happened.type == happened.KeyReleased && happened.key.code >= 0)
                                std::cout << happened.key.code << ": EXIT SPLASH";
                                return;
                }

                std::cout << "Splash. ";
                window.draw(_splashSprite);
                window.display();
        }
}

sf::Texture Splash::_splashTexture;
sf::Sprite Splash::_splashSprite;

As I said, this is just my attempt to get the splash screen working and at the moment it's probably wrong in a number of places and in a number of ways (which I am happy to hear too).

Until I mouse over the SFML window the command window prints "Splash!" over and over. As soon as I mouse over it stops and returns to loop.cpp. If the window loads under the mouse pointer it never starts to "Splash!" The cout to get the key code doesn't print anything when the program switches to the loop either.

Can someone help my by explaining why? I accept this is almost certainly not the way to do what I want, but it also feels like, even if it's wrong, it shouldn't be wrong in this way. If that makes sense.

Thanks for any help.
« Last Edit: January 08, 2014, 09:46:29 pm by sleeter »

Omega

  • Newbie
  • *
  • Posts: 29
    • View Profile
Re: [SFML 2.1 with VS2012] Event Help - keyboard and mouse problem
« Reply #1 on: January 08, 2014, 02:33:54 am »
It's hard for me to tell, since this isn't a minimal example, but I can already tell that you're trying to handle one window's events in 3 different places which indicates to me a starting point to finding a solution to your problem.

I suggest handling a single window's events in one place and acting on events via a state variable. For example, if the state is "showing splash screen", then while that is true, show the splash screen until an event (such as any key released) occurs that turns that variable false which will break the loop and allow you to continue to the next subroutine.

eigenbom

  • Full Member
  • ***
  • Posts: 228
    • View Profile
Re: [SFML 2.1 with VS2012] Event Help - keyboard and mouse problem
« Reply #2 on: January 08, 2014, 03:55:56 am »
Yep you should handle all events in one place. Your current bug is because of this code:
Code: [Select]
            if(happened.type == happened.KeyReleased && happened.key.code >= 0)
                std::cout << happened.key.code << ": EXIT SPLASH";
                return;
        }


You need to surround both lines with braces.

sleeter

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: [SFML 2.1 with VS2012] Event Help - keyboard and mouse problem
« Reply #3 on: January 08, 2014, 09:46:12 pm »
Thanks a lot Eigenbom! I completely failed to spot that the return was outside braces so triggered for every action on the window.  :-[

Thanks also for the advice Omega, I've moved my window event handling to one place and created a switch to handle what specific thing to do in each state.

Thanks for the help. I knew it would be a bone-head mistake on my part. :)

eigenbom

  • Full Member
  • ***
  • Posts: 228
    • View Profile
Re: [Solved] [SFML 2.1 with VS2012] Event Help - keyboard and mouse problem
« Reply #4 on: January 08, 2014, 10:15:29 pm »
Ha, no worries. That's why you should make a habit to always use braces in if statements, even if there's just one line. ;)

sleeter

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: [Solved] [SFML 2.1 with VS2012] Event Help - keyboard and mouse problem
« Reply #5 on: January 08, 2014, 11:09:09 pm »
I probably should, yes. But it looks neater to me to not use them when the situation doesn't need braces. Would have saved me a red face here though.

if(foo == bar) FooBar();

Just looks neater and nicer than:

if(foo == bar) {
    FooBar();
}

Or as I see a lot:

if(foo == bar)
{
    FooBar();
}

Is there a code-related reason to use the third format over the second? From what I've read and seen so far it seems like it's just style preference.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: [Solved] [SFML 2.1 with VS2012] Event Help - keyboard and mouse problem
« Reply #6 on: January 08, 2014, 11:11:36 pm »
For example, I don't use any of the three styles. What I use:
if (foo == bar)
    FooBar();

I don't like putting multiple statements on a single line, it makes it very easy to miss important parts when quickly looking at code.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

sleeter

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: [Solved] [SFML 2.1 with VS2012] Event Help - keyboard and mouse problem
« Reply #7 on: January 08, 2014, 11:30:18 pm »
The style you prefer, Nexus, is the one I've used above, but I missed the necessary braces which fixed my code nicely. :-)

I'm going to try to force myself to use braces going forward. There seems no real downside but quite a good reason to do so.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: [Solved] [SFML 2.1 with VS2012] Event Help - keyboard and mouse problem
« Reply #8 on: January 09, 2014, 12:27:38 am »
The style you prefer, Nexus, is the one I've used above, but I missed the necessary braces which fixed my code nicely. :-)
Yes, but you see very fast if there are two indented statements below an if keyword. This directly looks suspicious.

I know you made the mistake nevertheless :P
But I would rather train to recognize such situations instead of enforcing a more verbose code style.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything