Thursday, February 14, 2013

Quiz button lockout system using Python & Pygame


I read the following post on the Raspberry Pi forum where somebody was looking for a quiz button system for 10 buttons where only the first button pressed was registered.
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=78&t=32039

I posted a replay saying this should be possible with Python as it has an event queue so you should be able to find out which button was pressed first. I also mentioned that starting with a cheap USB gamepad would give the 10 buttons with little wiring effort and no need to do anything with the GPIO.

After posting instead of feeling like I helped somebody I mainly felt I had given them homework.
So, I decided to see if with the help of Google I could actually do the code.

Following a bit of tinkering and searching and getting spacing wrong and forgetting the colons at the end of lines I put together something quite rough that does the job.

I posted this back to the forum, but also the code is below.


The code is for four (4) buttons using the arrow keys on the keyboard.
It waits for a keys to be pressed.
Checks if it is one of the 'button' keys and registers the first button by changing the colour of that players on screen button to red.
It then waits until the 'Return' key is pressed and resets the buttons to black.

This provides the lockout system required and only registers the first button pressed.


#! /usr/bin/python
# Import a library of functions called 'pygame'
import pygame

# Initialize the game engine
pygame.init()

# Define the colors we will use in RGB format
black = [ 0, 0, 0]
white = [255,255,255]
red = [255, 0, 0]

# Set the height and width of the screen
size=[800,600]
screen=pygame.display.set_mode(size)
# Fill the screen White
screen.fill(white)
# Put something in the application Bar
pygame.display.set_caption("Testing key presses")

# Set the font for the text. Windows computer so usd Ariel
myfont = pygame.font.SysFont("Ariel", 30)

# Created Variable for the text on the screen
label = myfont.render("Quiz Buttons!", 1, black)
player1 = myfont.render("Player 1", 1, black)
player2 = myfont.render("Player 2", 1, black)
player3 = myfont.render("Player 3", 1, black)
player4 = myfont.render("Player 4", 1, black)

# Draw the 4 empty rectangles for the players
pygame.draw.rect(screen, black, (20,200,150,150), 0)
pygame.draw.rect(screen, black, (210,200,150,150), 0)
pygame.draw.rect(screen, black, (400,200,150,150), 0)
pygame.draw.rect(screen, black, (590,200,150,150), 0)

# put the text on the screen
screen.blit(label, (10, 10))
screen.blit(player1, (20, 150))
screen.blit(player2, (210, 150))
screen.blit(player3, (400, 150))
screen.blit(player4, (590, 150))

# show the whole thing
pygame.display.flip()

done=False # used to allow exit when you click close on the window
first = 0 # used to signify the first key pressed and stops other being used
waitReset = 0 # Reset section for the while loop

while done==False: # keep going unless I exit application

    # Stay in the loop until one of the 'button' keys is pressed
    while first==0 and done==False:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done=True
         
            # User pressed down on a key and it is not the first one
            if event.type == pygame.KEYDOWN and first==0:

                # Figure out which arrow key
                # Check of LEFT arrow key and that it was the first key pressed
                if event.key == pygame.K_LEFT and first==0:
                    print("left key pressed.") # Print to console
                    pygame.draw.rect(screen, red, (20,200,150,150), 0) # colour rectangle red
                    first=1 # set first to 1 so no other key presses will count
                if event.key == pygame.K_RIGHT and first==0:
                    print("right key pressed.")
                    pygame.draw.rect(screen, red, (210,200,150,150), 0)
                    first=1
                if event.key == pygame.K_UP and first==0:
                    print("up key pressed.")
                    pygame.draw.rect(screen, red, (400,200,150,150), 0)
                    first=1
                if event.key == pygame.K_DOWN and first==0:
                    print("down key pressed.")
                    pygame.draw.rect(screen, red, (590,200,150,150), 0)
                    first=1
                pygame.display.flip()
                # a 'button' was pressed and shown on screen
                # now got to the reset code

    # loop waiting until the 4 'button' are reset
    waitReset=0
    while waitReset==0 and done == False:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    done=True

                # User pressed down on a key
                if event.type == pygame.KEYDOWN:
                # Pressed Return Key which does a reset
                    if event.key == pygame.K_RETURN:
                        print("reset.")
                        # Draw the 4 empty rectangles for the players
                        pygame.draw.rect(screen, black, (20,200,150,150), 0)
                        pygame.draw.rect(screen, black, (210,200,150,150), 0)
                        pygame.draw.rect(screen, black, (400,200,150,150), 0)
                        pygame.draw.rect(screen, black, (590,200,150,150), 0)   
                        first=0
                        waitReset=1
                        pygame.display.flip()
            
            
# Quit in a clean way when done=True
pygame.quit ()


Next I will expand this to add the score and also run it full screen. 
Possibly even have sounds when the buttons are pressed.