taylorflatt / CS391

CS391-001 Game Programming Project
GNU General Public License v2.0
0 stars 0 forks source link

Keyboard Event #1

Closed taylorflatt closed 9 years ago

taylorflatt commented 9 years ago

For some reason, there is an issue where keyboard presses are being "remembered". If I have two game states and to traverse them, you must press keys on the keyboard, creating conditionals is a simple solution. Below is what I did:

       if(menu.getState() == TITLE):
            for event in pygame.event.get():
                '''Here is where the key is carried over. If RETURN is pressed, we have problems.'''
                if(event.type == pygame.KEYDOWN):
                    state = menu.setState(CREATION)
                    print('We pressed a key.')

                elif(event.type == pygame.QUIT):
                    pygame.quit; sys.exit();

        if(menu.getState() == CREATION):
            screen.fill(Color.black)     

            while(enteredName == False):
                events = pygame.event.get() #Sets variable events so we can access our key presses

                '''Extra events MUST go between my events declaration and the update to my textbox. If not, weird things will happen.'''
                '''ALLOW EXIT'''
                for event in events:
                    if event.type == QUIT: return

                if(menu.isKeyPressed(pygame.K_RETURN) == True):
                    playerName = enterNameField.update(events) #Sets the player name so we can use it elsewhere
                    menu.setState(MAIN) #Changes the game state to MAIN so we exit this game state.
                    print(enterNameField.update(events)) #Prints the player name from my array.
                    enteredName = True #Allows me to exit my while loop.

                enterNameField.update(events) #Adds the keys to the event array
                enterNameField.draw(screen) #Draws the keys
                pygame.display.flip() #Refresh the screen

My problem is that from the first game state, if return is pressed then it will enter straight into the next game state, then the while loop, then check the if conditional and see that RETURN was pressed (i.e that it is true) and enter that loop. It basically skips name creation if the return key is pressed when the title screen begins.

I have attempted to clear the event list both directly after it enters the initial loop in my first game state to change to CREATION state. I have also attempted it immediately after entering the CREATION game state. In fact, I have pulled the events from the event list to see if anything is being saved or carried over and it returns no events in the current queue. So not sure why that is happening.

taylorflatt commented 9 years ago

I figured out a sort of dirty fix for the issue. It kills two birds with one stone honestly. It is common to have a character requirement for games (min/max) so I decided to implement this to act as a precondition for entering the loop that will progress the player to the next screen (solving the issue if the player presses enter on the initial screen skipping name creation). The code fix is below:

if(menu.getState() == TITLE):
            for event in pygame.event.get():
                '''Here is where the key is carried over. If RETURN is pressed, we have problems.'''
                if(event.type == pygame.KEYDOWN):
                    state = menu.setState(CREATION)
                    print('We pressed a key.')

                elif(event.type == pygame.QUIT):
                    pygame.quit; sys.exit();

        if(menu.getState() == CREATION):
            screen.fill(Color.black)     

            while(enteredName == False):
                events = pygame.event.get() #Sets variable events so we can access our key presses

                '''Extra events MUST go between my events declaration and the update to my textbox. If not, weird things will happen.'''
                '''ALLOW EXIT'''
                for event in events:
                    if event.type == QUIT: return

                if(menu.isKeyPressed(pygame.K_RETURN) == True and enterNameField.update(events) == None):
                    enterNameField.update(events) #Let's us handle the error of having less than 3 characters in our name.
                    print('Errored out!') #Debug

                elif(menu.isKeyPressed(pygame.K_RETURN) == True and len(enterNameField.update(events)) >= 3 and enterNameField.update(events) != None):
                    playerName = enterNameField.update(events) #Sets the player name so we can use it elsewhere
                    menu.setState(MAIN) #Changes the game state to MAIN so we exit this game state.
                    print(enterNameField.update(events)) #Prints the player name from my array.
                    print(len(enterNameField.update(events)))
                    enteredName = True #Allows me to exit my while loop.

                enterNameField.update(events) #Adds the keys to the event array
                enterNameField.draw(screen) #Draws the keys
                pygame.display.flip() #Refresh the screen

Effectively, this uses textbox I create (and the text entered therein) to run a quick check on whether they hit a certain character limit or not.

This approach is MUCH preferred to setting a variable outside the while loop and then increment based on key press because you don't have to deal with anything from past events. The counter, in my case, begins fresh upon entering the game state.

The only thing you have to take care of is the type error which is encountered if you don't meet character limit and attempt to progress by pressing enter. I simply check if 'None Type' is returned and then run my update method from TextInputManager again to keep the loop going.

Unfortunately, the backspace issue still exists. That is a separate issue.