427 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			427 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#!/usr/bin/env python
 | 
						|
#coding=utf-8
 | 
						|
 | 
						|
import pygame, signal, sys, time, os, RPi.GPIO as GPIO
 | 
						|
from PIL import Image
 | 
						|
from pygame.locals import *
 | 
						|
 | 
						|
#GPIO for Buttons
 | 
						|
startPin = 32
 | 
						|
errorPin = 31
 | 
						|
shutdownPin = 3
 | 
						|
 | 
						|
#GPIO for LED
 | 
						|
pin_red = 22
 | 
						|
pin_green = 18
 | 
						|
pin_blue = 16
 | 
						|
 | 
						|
#initialise gpio
 | 
						|
GPIO.setmode(GPIO.BOARD)
 | 
						|
GPIO.setup(startPin, GPIO.IN)
 | 
						|
GPIO.setup(errorPin, GPIO.IN)
 | 
						|
GPIO.setup(shutdownPin, GPIO.IN)
 | 
						|
 | 
						|
#other constants
 | 
						|
timePerError = 5 # every time the wire is touched, some time is added as penalty.
 | 
						|
screenSizeX = 1920
 | 
						|
screenSizeY = 1080
 | 
						|
 | 
						|
#initialise the game
 | 
						|
pygame.init()
 | 
						|
 | 
						|
#colors
 | 
						|
greenColor = pygame.Color(42, 217, 13)
 | 
						|
blackColor = pygame.Color(0, 0, 0)
 | 
						|
whiteColor = pygame.Color(255, 255, 255)
 | 
						|
yellowColor = pygame.Color(255, 215, 0)
 | 
						|
grayColor = pygame.Color(196, 202, 206)
 | 
						|
brownColor = pygame.Color(177, 86, 15)
 | 
						|
mainFontColor = blackColor
 | 
						|
 | 
						|
#fonts
 | 
						|
font1 = pygame.font.Font('freesansbold.ttf', 90)
 | 
						|
font2 = pygame.font.Font('freesansbold.ttf', 65)
 | 
						|
font3 = pygame.font.Font('freesansbold.ttf', 45)
 | 
						|
 | 
						|
#predefinition of led variables, for later global use
 | 
						|
red = ""
 | 
						|
green = ""
 | 
						|
blue = ""
 | 
						|
 | 
						|
# preset highscores
 | 
						|
hs1_name = "Fritz"
 | 
						|
hs2_name = "Bernd"
 | 
						|
hs3_name = "Max"
 | 
						|
hs1_time = 100
 | 
						|
hs2_time = 200
 | 
						|
hs3_time = 300
 | 
						|
 | 
						|
# name length for highscores
 | 
						|
MAX_NAME_LENGTH = 10
 | 
						|
 | 
						|
def get_image_width(filepath):
 | 
						|
    return ((Image.open(filepath).size)[0])
 | 
						|
 | 
						|
def get_image_height(filepath):
 | 
						|
    return ((Image.open(filepath).size)[1])
 | 
						|
 | 
						|
def signal_handler(sig, frame):
 | 
						|
        # signal handler, later called to interpret
 | 
						|
        # ctrl+c as "quit" rather than "abort"
 | 
						|
        print('Programm exiting')
 | 
						|
        exit_application()
 | 
						|
 | 
						|
def led_init():
 | 
						|
        # initialises the LED pins
 | 
						|
        # mind that the pins for the LEDs are pullup by default,
 | 
						|
        # which is on purpose, since this causes the LED strip to 
 | 
						|
        # be turned off when the program isnt running or their state
 | 
						|
        # is undefined
 | 
						|
 | 
						|
        # set the led pins to be outputs
 | 
						|
        # careful: these pins dont drive the 
 | 
						|
        # led strip themselves, but rather 3 
 | 
						|
        # n-channel mosfets, type IRLZ34N
 | 
						|
        global red,green,blue
 | 
						|
        GPIO.setup(pin_red, GPIO.OUT)
 | 
						|
        GPIO.setup(pin_green, GPIO.OUT)
 | 
						|
        GPIO.setup(pin_blue, GPIO.OUT)
 | 
						|
        
 | 
						|
        # set the pwm frequency to 100
 | 
						|
        # if you experience strobing, try changing
 | 
						|
        # the number
 | 
						|
        red = GPIO.PWM(pin_red, 100)        
 | 
						|
        blue = GPIO.PWM(pin_blue, 100)
 | 
						|
        green = GPIO.PWM(pin_green, 100)
 | 
						|
 | 
						|
        # start pwm generation with a duty cycle of 0
 | 
						|
        green.start(0)
 | 
						|
        blue.start(0)
 | 
						|
        red.start(0)
 | 
						|
 | 
						|
def change_green(amount):
 | 
						|
        # takes an input from 0 to 255 and converts it to Duty Cycle
 | 
						|
        # to be used by change_led_colour
 | 
						|
        global green
 | 
						|
        factor = 100/255
 | 
						|
        green.ChangeDutyCycle(amount*factor)
 | 
						|
 | 
						|
def change_blue(amount):
 | 
						|
        # takes an input from 0 to 255 and converts it to Duty Cycle
 | 
						|
        # to be used by change_led_colour
 | 
						|
        global blue
 | 
						|
        factor = 100/255
 | 
						|
        blue.ChangeDutyCycle(amount*factor)
 | 
						|
    
 | 
						|
def change_red(amount):
 | 
						|
        # takes an input from 0 to 255 and converts it to Duty Cycle
 | 
						|
        # to be used by change_led_colour
 | 
						|
        global red
 | 
						|
        factor = 100/255
 | 
						|
        red.ChangeDutyCycle(amount*factor)
 | 
						|
 | 
						|
def change_led_colour(red_amount,green_amount,blue_amount):
 | 
						|
        # sets an RGB value for the led strip.
 | 
						|
        global red,green,blue
 | 
						|
        if red_amount < 0 or red_amount > 255 or green_amount < 0 or green_amount > 255 or blue_amount < 0 or blue_amount > 255:
 | 
						|
            led_alert()
 | 
						|
            return false
 | 
						|
        change_red(red_amount)
 | 
						|
        change_blue(blue_amount)
 | 
						|
        change_green(green_amount)
 | 
						|
 | 
						|
def change_led_speed(colour, speed):
 | 
						|
        #changes the speed of the LED pwm
 | 
						|
        global red,green,blue
 | 
						|
 | 
						|
        if colour == "red":
 | 
						|
            red.ChangeDutyCycle(speed)
 | 
						|
        elif colour == "green":
 | 
						|
            green.ChangeDutyCycle(speed)
 | 
						|
        elif colour == "blue":
 | 
						|
            blue.ChangeDutyCycle(speed)
 | 
						|
        else:
 | 
						|
            return false
 | 
						|
 | 
						|
def led_alert():
 | 
						|
        # stops the running program for 10 seconds
 | 
						|
        # causes the red LED to flash
 | 
						|
        # use as error message
 | 
						|
        change_led_colour(100, 0, 0)
 | 
						|
        change_led_speed(red, 1)
 | 
						|
        for i in range(1,10):
 | 
						|
            time.sleep(1)
 | 
						|
        change_led_colour(100, 100, 100)
 | 
						|
        change_led_speed(red, 100)
 | 
						|
 | 
						|
def toggle_fullscreen():
 | 
						|
        screen = pygame.display.get_surface()
 | 
						|
        tmp = screen.convert()
 | 
						|
        caption = pygame.display.get_caption()
 | 
						|
        cursor = pygame.mouse.get_cursor() # Duoas 16-04-2007 
 | 
						|
 | 
						|
        w,h = screen.get_width(),screen.get_height()
 | 
						|
        flags = screen.get_flags()
 | 
						|
        bits = screen.get_bitsize()
 | 
						|
 | 
						|
        pygame.display.quit()
 | 
						|
        pygame.display.init()
 | 
						|
 | 
						|
        screen = pygame.display.set_mode((w,h),flags^FULLSCREEN,bits)
 | 
						|
        screen.blit(tmp,(0,0))
 | 
						|
        pygame.display.set_caption(*caption)
 | 
						|
 | 
						|
        pygame.key.set_mods(0) #HACK: work-a-round for a SDL bug??
 | 
						|
 | 
						|
        pygame.mouse.set_cursor( *cursor ) # Duoas 16-04-2007
 | 
						|
        return screen
 | 
						|
 | 
						|
def clearScreen():
 | 
						|
        print("filled screen")
 | 
						|
        screen.fill(whiteColor)
 | 
						|
        return
 | 
						|
 | 
						|
def handle_events():
 | 
						|
        print("Status der Pins:")
 | 
						|
        print("Start Pin:", GPIO.input(startPin))
 | 
						|
        print("Error Pin:", GPIO.input(errorPin))
 | 
						|
        print("Stop Pin:", GPIO.input(shutdownPin))
 | 
						|
 | 
						|
        #if GPIO.input(shutdownPin) == True:
 | 
						|
                #shutdown_raspberry()
 | 
						|
        for event in pygame.event.get():
 | 
						|
                if event.type == KEYDOWN and event.key == K_ESCAPE:
 | 
						|
                        exit_application()
 | 
						|
                elif event.type == KEYDOWN and event.key == K_q: 
 | 
						|
                        shutdown_raspberry()      
 | 
						|
 | 
						|
        time.sleep(0.1)
 | 
						|
        return
 | 
						|
 | 
						|
def exit_application():
 | 
						|
        pygame.quit()
 | 
						|
        GPIO.cleanup()
 | 
						|
        sys.exit()
 | 
						|
        return
 | 
						|
 | 
						|
def shutdown_raspberry():
 | 
						|
        pygame.quit()
 | 
						|
        GPIO.cleanup()
 | 
						|
        os.system("sudo shutdown -h now")
 | 
						|
        return
 | 
						|
 | 
						|
def enterName():
 | 
						|
        clearScreen()
 | 
						|
        print('text entry started')
 | 
						|
        name = ''
 | 
						|
        while True:
 | 
						|
                clearScreen()
 | 
						|
 | 
						|
                highscore_surface = font1.render('High Score!', True, mainFontColor)
 | 
						|
                highscore_rectangle = highscore_surface.get_rect()
 | 
						|
                highscore_rectangle.topleft = (700, 210)
 | 
						|
 | 
						|
                screen.blit(highscore_surface, highscore_rectangle)
 | 
						|
 | 
						|
 | 
						|
                textbox_surface = font2.render('Enter name: ' + str(name), True, mainFontColor)
 | 
						|
                textbox_rectangle = textbox_surface.get_rect()
 | 
						|
                textbox_rectangle.topleft = (700, 350)
 | 
						|
                screen.blit(textbox_surface, textbox_rectangle)
 | 
						|
                pygame.display.flip()
 | 
						|
                for event in pygame.event.get():
 | 
						|
                        if len(name) < MAX_NAME_LENGTH:
 | 
						|
                                if event.type == KEYDOWN:
 | 
						|
                                        if event.key == pygame.K_BACKSPACE:
 | 
						|
                                            name = name[:-1]
 | 
						|
                                        elif event.key == pygame.K_RETURN:
 | 
						|
                                            clearScreen()
 | 
						|
                                            return name
 | 
						|
                                        else:
 | 
						|
                                            name += event.unicode
 | 
						|
                        elif event.key == pygame.K_BACKSPACE:
 | 
						|
                                name = name[:-1]
 | 
						|
 | 
						|
                        elif event.type == KEYDOWN and event.key == pygame.K_RETURN:
 | 
						|
                                clearScreen()
 | 
						|
                                return name
 | 
						|
        clearScreen()
 | 
						|
        name = 'Error'
 | 
						|
        return name
 | 
						|
 | 
						|
def checkHighscores(time):
 | 
						|
    global hs1_time, hs2_time, hs3_time, hs1_name, hs2_name, hs3_name
 | 
						|
    if time <= hs1_time:
 | 
						|
        print ('new high score:'+str(time))
 | 
						|
        #make the second the third
 | 
						|
        hs3_time = hs2_time
 | 
						|
        hs3_name = hs2_name
 | 
						|
 | 
						|
        #make the first the second
 | 
						|
        hs2_time = hs1_time
 | 
						|
        hs2_name = hs1_name
 | 
						|
 | 
						|
        #new high score
 | 
						|
        hs1_time = time
 | 
						|
        hs1_name = enterName()
 | 
						|
        return
 | 
						|
    elif time <= hs2_time:
 | 
						|
        print ('new second:'+str(time))
 | 
						|
 | 
						|
        #make the second the third
 | 
						|
        hs3_time = hs2_time
 | 
						|
        hs3_name = hs2_name
 | 
						|
 | 
						|
        #new second time
 | 
						|
        hs2_time = time
 | 
						|
        hs2_name = enterName()
 | 
						|
        return
 | 
						|
    elif time <= hs3_time:
 | 
						|
        print ('new third:'+str(time))
 | 
						|
        hs3_time = time
 | 
						|
        hs3_name = enterName()
 | 
						|
        return
 | 
						|
    else:
 | 
						|
        return
 | 
						|
 | 
						|
 | 
						|
#signal handing for controlled exit via ctrl+c
 | 
						|
signal.signal(signal.SIGINT, signal_handler)
 | 
						|
 | 
						|
#hide mouse
 | 
						|
pygame.mouse.set_visible(False)
 | 
						|
 | 
						|
screen = pygame.display.set_mode((screenSizeX, screenSizeY), pygame.FULLSCREEN)
 | 
						|
#pygame.display.set_caption('Heisser Draht') # not required for fullscreen application
 | 
						|
 | 
						|
#screen = toggle_fullscreen()
 | 
						|
 | 
						|
# define image variables 
 | 
						|
img_itlablogo = 'img/itlablogo.png'
 | 
						|
img_itlablogo_image  = pygame.image.load(img_itlablogo)
 | 
						|
img_itlablogo_imagex = get_image_width(img_itlablogo)
 | 
						|
img_itlablogo_imagey = get_image_height(img_itlablogo)
 | 
						|
 | 
						|
#initialise led strip
 | 
						|
led_init()
 | 
						|
 | 
						|
while True: # main loop
 | 
						|
#global label storage
 | 
						|
        clearScreen()
 | 
						|
        print("New game starting")
 | 
						|
        change_led_colour(10,140,10)
 | 
						|
        time_surface = 0
 | 
						|
        errors_surface = 0
 | 
						|
        time_rectangle = 0
 | 
						|
        errors_rectangle = 0
 | 
						|
 | 
						|
        header_surface = font1.render('Dr' + u'ü' + 'cken Sie Start!', True, mainFontColor)
 | 
						|
        header_rectangle = header_surface.get_rect()
 | 
						|
        header_rectangle.topleft = (560, 250)
 | 
						|
 | 
						|
        highscore_header_surface = font2.render('Highscores:', True, mainFontColor)
 | 
						|
        highscore_header_rectangle = highscore_header_surface.get_rect()
 | 
						|
        highscore_header_rectangle = (770, 410)
 | 
						|
 
 | 
						|
        score1_surface = font3.render(hs1_name + ": " + str(hs1_time) + 's', True, yellowColor)
 | 
						|
        score1_rectangle = score1_surface.get_rect()
 | 
						|
        score1_rectangle.topleft = (820, 540)
 | 
						|
 | 
						|
        score2_surface = font3.render(hs2_name + ": " + str(hs2_time) + 's', True, grayColor)
 | 
						|
        score2_rectangle = score2_surface.get_rect()
 | 
						|
        score2_rectangle.topleft = (820, 630)
 | 
						|
 | 
						|
        score3_surface = font3.render(hs3_name + ": " + str(hs3_time) + 's', True, brownColor)
 | 
						|
        score3_rectangle = score3_surface.get_rect()
 | 
						|
        score3_rectangle.topleft = (820, 720)
 | 
						|
        
 | 
						|
        pygame.draw.rect(screen,blackColor, (500, 200, (screenSizeX-500*2), (screenSizeY-200*2)), 5)
 | 
						|
        
 | 
						|
        screen.blit(header_surface, header_rectangle)
 | 
						|
        screen.blit(highscore_header_surface, highscore_header_rectangle)
 | 
						|
        screen.blit(score1_surface, score1_rectangle)
 | 
						|
        screen.blit(score2_surface, score2_rectangle)
 | 
						|
        screen.blit(score3_surface, score3_rectangle)
 | 
						|
        screen.blit(img_itlablogo_image, (screenSizeX-img_itlablogo_imagex-20, screenSizeY-img_itlablogo_imagey-20))
 | 
						|
 | 
						|
        pygame.display.flip()
 | 
						|
 | 
						|
        while GPIO.input(startPin) == False: #wait for the user to press start button
 | 
						|
                handle_events()
 | 
						|
 | 
						|
        errors = 0
 | 
						|
        errorAdded = False
 | 
						|
 | 
						|
        #justStarted = True
 | 
						|
 | 
						|
        header_surface = font1.render('Spiel l' + u'ä' + 'uft!', True, mainFontColor)
 | 
						|
        time.sleep(5)
 | 
						|
 | 
						|
        start_time = int(time.time())
 | 
						|
 | 
						|
        change_led_colour(10,10,100)
 | 
						|
 | 
						|
 | 
						|
        while True: # game running
 | 
						|
                print("Game running normally")
 | 
						|
 | 
						|
                handle_events()
 | 
						|
 | 
						|
                if GPIO.input(errorPin) == True:
 | 
						|
                        if errorAdded == False:
 | 
						|
                                errors += 1
 | 
						|
                                int_time = int(time.time()) - start_time + errors * timePerError
 | 
						|
                                errorAdded = True
 | 
						|
                        else:
 | 
						|
                                errorAdded = False 
 | 
						|
 | 
						|
                int_time = int(time.time()) - start_time
 | 
						|
 | 
						|
                time_surface = font2.render('Zeit: ' + str(int_time) + 's', True, mainFontColor)
 | 
						|
                time_rectangle = time_surface.get_rect()
 | 
						|
                time_rectangle.topleft = (640, 480)
 | 
						|
 | 
						|
                errors_surface = font2.render('Fehler: ' + str(errors), True, mainFontColor)
 | 
						|
                errors_rectangle = errors_surface.get_rect()
 | 
						|
                errors_rectangle.topleft = (640, 560)
 | 
						|
 | 
						|
                clearScreen()
 | 
						|
                screen.blit(errors_surface, errors_rectangle) #errors
 | 
						|
                screen.blit(time_surface, time_rectangle) #time 
 | 
						|
                screen.blit(header_surface, header_rectangle) #header
 | 
						|
 | 
						|
                pygame.display.flip()
 | 
						|
 | 
						|
                #if GPIO.input(startPin) == False:
 | 
						|
                #        justStarted = False
 | 
						|
                #if GPIO.input(startPin) == True and justStarted == False:
 | 
						|
                if GPIO.input(startPin) != True:
 | 
						|
 | 
						|
                        change_led_colour(100,10,10)
 | 
						|
 | 
						|
                        print("Game ended because start pin wasnt true")
 | 
						|
 | 
						|
                        checkHighscores(int_time)
 | 
						|
 | 
						|
                        clearScreen()
 | 
						|
                        header_surface = font1.render('Game over!', True, mainFontColor)
 | 
						|
 | 
						|
                        screen.blit(errors_surface, errors_rectangle) #errors
 | 
						|
                        screen.blit(time_surface, time_rectangle) #time 
 | 
						|
                        screen.blit(header_surface, header_rectangle) #header
 | 
						|
 | 
						|
                        pygame.display.flip()
 | 
						|
 | 
						|
                        #while GPIO.input(startPin) == False:
 | 
						|
                        #        handle_events()
 | 
						|
 | 
						|
                        #while GPIO.input(startPin) == True:
 | 
						|
                        #        handle_events()
 | 
						|
 | 
						|
                        #while GPIO.input(startPin) == False:
 | 
						|
                        #        handle_events()
 | 
						|
 | 
						|
                        clearScreen()
 | 
						|
                        time.sleep(10)
 | 
						|
                        break
 |