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

Author Topic: Pressing Enter causes two screen switches instead of 1!  (Read 6708 times)

0 Members and 1 Guest are viewing this topic.

supdawg

  • Newbie
  • *
  • Posts: 33
    • View Profile
Pressing Enter causes two screen switches instead of 1!
« on: November 28, 2012, 06:26:59 am »
This is my event loop.
while(Window.isOpen()){
    while(Window.pollEvent(ScreenManager::getInstance().event)){
        if(ScreenManager::getInstance().event.type == sf::Event::Closed || ScreenManager::getInstance().event.key.code == sf::Keyboard::Escape){
          Window.close();
        }//end of if Event::Closed

        ScreenManager::getInstance().update(ScreenManager::getInstance().event);
    }//end of while/if Poll event

    Window.clear(sf::Color(0, 0, 0));
    ScreenManager::getInstance().draw(Window);
    Window.display();
  }//end of while isOpen

This changes from SplashScreen to TitleScreen
void SplashScreen::update(const sf::Event event){
  if(input->keyPressed(sf::Keyboard::T))
    ScreenManager::getInstance().addScreen(new TitleScreen()); //input*/

}//end of update()

This changes from TitleScreen to SplashScreen
void TitleScreen::update(const sf::Event event){
  if(input->keyPressed(sf::Keyboard::S))
    ScreenManager::getInstance().addScreen(new SplashScreen());//end of if enter is pressed*/
}//end of update()

If i have separate keys (S to change to SplashScreen and T to change to TitleScreen) it works fine. It changes screens nicely.
However, once i made both the keys the RETURN key, (i.e. press enter to change to SplashScreen and press Enter again to change to TitleScreen) it doesnt work. What it does is if i press enter once, it changes screens and changes back quickly. Note that i dont hold the enter key, i just press it once. I was thinking maybe the event stack has two return keys on it even though i pressed enter once? I have no idea how to fix it

Im on Mac OSX Mountain Lion
I use sublime text 2 with clang++

gyscos

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
Re: Pressing Enter causes two screen switches instead of 1!
« Reply #1 on: November 28, 2012, 07:12:17 am »
You don't check the event itself, but the state of the key. Maybe checking for a real KeyPressed event could help things : if some mouse event happen while you press the key for instance, then you may see such behaviour.

supdawg

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Pressing Enter causes two screen switches instead of 1!
« Reply #2 on: November 28, 2012, 08:53:51 am »
Oh sorry i forgot to post my InputManager code. I do check the event here in another class

bool InputManager::keyPressed(sf::Keyboard::Key key){
  if(ScreenManager::getInstance().event.key.code == key) return true;
  return false;
}//end of keyPressed(int)

Basically, my inputManager class handles input by checking if the event.key.code matches with the given key in the parameter. the event here is the same event that i got from pollEvent in main.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
AW: Pressing Enter causes two screen switches instead of 1!
« Reply #3 on: November 28, 2012, 09:10:00 am »
What gyscos meant is that you have to check first if the event type is KeyPressed or KeyReleased before you can check the key code. If you don't do that you run into undefined behaviour since key code can hold anything...
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

supdawg

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Pressing Enter causes two screen switches instead of 1!
« Reply #4 on: November 29, 2012, 03:04:56 am »
im still confused about why event.key.code can have something random. does it not have the code of the key pressed?

and ok so i tried checking for event.KeyPressed like this:

bool InputManager::keyPressed(sf::Keyboard::Key key){
  if(ScreenManager::getInstance().event.KeyPressed && ScreenManager::getInstance().event.key.code == key) return true;
  return false;
}//end of keyPressed

but the problem doesnt go away. if i press enter it switches from splashscreen to titlescreen and back.

im sorry im so noob :(. im kind of new to graphics and windows.

supdawg

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Pressing Enter causes two screen switches instead of 1!
« Reply #5 on: November 29, 2012, 04:31:26 am »
ok so i changed it to this and it works.
bool InputManager::keyPressed(sf::Keyboard::Key key){
  if(ScreenManager::getInstance().event.type == sf::Event::KeyPressed && ScreenManager::getInstance().event.key.code == key) return true;
  return false;
}//end of keyPressed

and i have one more question. i have seen some people use vectors of sf::Keyboard::Key to check input. can someone tell me what is is the benefit of using a vector of keys rather just checking individual keys like i did above?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
AW: Pressing Enter causes two screen switches instead of 1!
« Reply #6 on: November 29, 2012, 08:39:56 am »
The question is why you don't use sf::Keyboard::isKeyPressed() directly instead of doing the same thing with events, which won't be in real time?

A vector of keys was probably used for key mapping, but I haven't seen that anywhere.

Also your code probably doesn't work since sf::Event::KeyPressed gets only trigerred once.
« Last Edit: November 29, 2012, 08:41:30 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

gyscos

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
Re: AW: Pressing Enter causes two screen switches instead of 1!
« Reply #7 on: November 29, 2012, 09:14:32 am »
The question is why you don't use sf::Keyboard::isKeyPressed() directly instead of doing the same thing with events, which won't be in real time?

What do you mean ? Events are in real time. Also, since he only wants to trigger it once when the user press the key, it's easier to use events as he did.
That's actually what I was talking about in the previous message : if he uses isKeyPressed on each event, and non-keyboard event happen while the key is pressed, he'll think the key was pressed several time, which is not true.

But the way you check for the event is not really intuitive... What if you need to check other keys ?
Is there a reason you don't use the double-switch structure (one switch on the event type, the other on the event's key or button) ? Have you read the tutorial ?

Also, on the code in the original post, you seemed to use different keys (T and S) for the two transitions, which would prevent the double-transition issue you mentioned...
« Last Edit: November 29, 2012, 09:16:34 am by gyscos »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
AW: Re: AW: Pressing Enter causes two screen switches instead of 1!
« Reply #8 on: November 29, 2012, 09:37:42 am »
What do you mean ? Events are in real time. Also, since he only wants to trigger it once when the user press the key, it's easier to use events as he did.
No they are not. ;)
In most cases you won't directly notice the difference but events aren't triggered in realtime. From the logic point of view; with sf::Keyboard::isKeyPressed you simply check for the state of the key which happens as you ask for it, the events get triggered by the OS and first have to propagate through some messages pipelines of the OS before they get to the application, which is not 100% in real time.
You could probably check that by not limiting the framerate and check for both and count the frames in between. There will be a franedifference between sf::Keynoard and events. ;)
Edit: Additionally events can get delayed if the OS is doing some heavy lifting.

If it makes sense in his case to use events? Maybe, but the name is then confusing, it should rather be: wasPressed or pressedOnce and not isPressed since that suggests the current state. ;)
« Last Edit: November 29, 2012, 09:45:33 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

supdawg

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Pressing Enter causes two screen switches instead of 1!
« Reply #9 on: November 30, 2012, 11:12:43 pm »
Double switch structure? whats that? I know that using a switch structure in the main while(isOpen) loop will allow you to detect cases .

In my main function, i will eventually have a switch case that detects what time of event it is (keypressed, closed etc etc) but then when i want to specifically check which key has been pressed, i use the inputManager functions which returns true or false based on which key has been pressed.

also sorry for asking multiple questions, but, in your opinions, if i have ScreenManager, GameScreen, SplashScreen, TitleScreen, InputManager, and Animation classes, which class should keep info about the time between frames?

I was thinking the ScreenManager should have a sf::Time member which holds the time between each frame. I want to keep track of the time between each frame such that if i want to control movement/ fading animations, i can change alpha values.

oh and yea my inputManager had S and T keys that change between screens but i changed it to the Return key.

and expl0it3r. so you're saying i should first check if the key is pressed by doing
sf::Keyboard::isKeypressed
and then i should check the actual key pressed by doing
event.key.code == key

and the reason to do this is because the event may be delayed so there might be a time difference?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Pressing Enter causes two screen switches instead of 1!
« Reply #10 on: November 30, 2012, 11:32:45 pm »
Double switch structure? whats that? I know that using a switch structure in the main while(isOpen) loop will allow you to detect cases .
That would be a nested switch statement (see below); but it really depends on what you want to achieve (e.g. use a separated function to process key events).
switch(event.type)
{
    case sf::Event::KeyPressed:
        switch(event.key.code)
        {
                case sf::Keyboard::T:
                    // Do T
                    break;
        }
        break;
}


In my main function, i will eventually have a switch case that detects what time of event it is (keypressed, closed etc etc) but then when i want to specifically check which key has been pressed, i use the inputManager functions which returns true or false based on which key has been pressed.
You just have to make sure that event.type is equal to sf::Event::KeyPressed before you check with the input manager. And you also have to pass the correct event, otherwise event.key.code will only contain a random number.

if i have ScreenManager, GameScreen, SplashScreen, TitleScreen, InputManager, and Animation classes, which class should keep info about the time between frames?
Depends which class references what and how things are structured.

and expl0it3r. so you're saying i should first check if the key is pressed by doing
sf::Keyboard::isKeypressed
and then i should check the actual key pressed by doing
event.key.code == key

and the reason to do this is because the event may be delayed so there might be a time difference?
No! :D
If you want to check the key code you first have to check event.type == sf::Event::KeyPressed (Just read the tutorial!!!) ;)
If you want to check in real time, if a key is pressed, then use sf::Keyboard::isPressed().
Think of this like this:
  • sf::Event: I wait until someone presses a key. (passive)
  • sf::Keyboard: At this moment I want to know if someone is pressing the key. (active)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

supdawg

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Pressing Enter causes two screen switches instead of 1!
« Reply #11 on: December 01, 2012, 12:42:23 am »
Ohh i get it now. That analogy makes it easier to understand.

And sorry to keep bothering but i am trying to achieve a fading animation during screen switches. i looked on the forum and people tried using a for loop to fade in and out and i tried something like this but it doesnt work. (what actually happens is i press enter, instead of fading away the screen just freezes for 2 seconds without dimming and then switches to the next screen) this is the code:

void SplashScreen::update(const sf::Event event, sf::RenderWindow &Window){
  if(input->keyPressed(sf::Keyboard::Return)){
    for(int i = opacity; i >= 0; i -= 5){ //opacity = 255
      Window.clear(sf::Color(0, 0, 0));
      text.setColor(sf::Color(255, 255, 255, i));
      Window.display();
    }
    ScreenManager::getInstance().addScreen(new TitleScreen()); //input*/
  }
}//end of update()

i was wondering how i can fade in and out. ive seen some people use the delta time between frames to fade in and out but why doesnt the above code work?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Pressing Enter causes two screen switches instead of 1!
« Reply #12 on: December 01, 2012, 01:04:54 am »
Ohh i get it now. That analogy makes it easier to understand.
I'm glad it helped. ;)

I am trying to achieve a fading animation during screen switches. i looked on the forum and people tried using a for loop to fade in and out and i tried something like this but it doesnt work.
No idea where you saw that but it's, as you've noticed yourself, obviously wrong. Fading is a 'process' that needs to be spread over multiple frames. If you do it in a loop and in between frames, the color value certainly gets reduced, but you'll never see anything, since it happens 'in between frames' and gets never drawn to the screen. ;)

i was wondering how i can fade in and out. ive seen some people use the delta time between frames to fade in and out but why doesnt the above code work?
Maybe you want to take a look at my SmallGameEngine, the code is simple, straight forward and should be quite clean (no global variables, no singletons, no (to me) 'strange' input processing).
The IntroState does also have a fading sf::RectangleShape.
The current implementation makes use of the fact that the framerate is limited to 60fps (window.setFramerateLimit(60)), but should actually also depend on the delta time. ;)
« Last Edit: December 01, 2012, 01:06:37 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

supdawg

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Pressing Enter causes two screen switches instead of 1!
« Reply #13 on: December 01, 2012, 01:53:55 am »
i thought i understood what a frame was but it seems not. in the for loop i call Window.display()... what i initially thought was every time you call Window.display()  it displays your contents to the Window and that is a one "frame". what exactly is a frame? if calling Window.display() doesnt mark the end of one frame and the beginning of the next frame then how exactly does it work?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Pressing Enter causes two screen switches instead of 1!
« Reply #14 on: December 01, 2012, 08:59:43 am »
Technically you could define it as such; so you're right and your code might show a fade, but the way you do it, is not really a goid one.
For a state you should just have one display call and do the logic separated from the drawing part. Again take a look at the SmallGamEngine; each state has an update() and a draw() function. display() is called only once in the draw function and the decision to increase the alpha value happens in the update() function. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/