diff options
| author | Robert Scheibe <robert.scheibe@mailbox.org> | 2020-06-18 11:37:11 +0200 | 
|---|---|---|
| committer | Robert Scheibe <robert.scheibe@mailbox.org> | 2020-06-18 11:37:11 +0200 | 
| commit | d3a4e5b0e664aea57c4cce59631785ff5b61eabf (patch) | |
| tree | ebfb8bddea356b72410ba9c2ead488deae2dfdf1 | |
initial commit
| -rw-r--r-- | README.txt | 28 | ||||
| -rw-r--r-- | joystick/disable.wav | bin | 0 -> 419318 bytes | |||
| -rw-r--r-- | joystick/enable.wav | bin | 0 -> 418996 bytes | |||
| -rwxr-xr-x | joystick/joystick-input.py | 69 | ||||
| -rwxr-xr-x | joystick/test-joystick.py | 22 | ||||
| -rw-r--r-- | pong/Pong.wav | bin | 0 -> 23292 bytes | |||
| -rw-r--r-- | pong/ball.py | 33 | ||||
| -rw-r--r-- | pong/paddle.py | 33 | ||||
| -rwxr-xr-x | pong/pong.py | 227 | ||||
| -rwxr-xr-x | tetris/tetris.py | 612 | ||||
| -rw-r--r-- | tetris/tetrisb.mid | bin | 0 -> 8612 bytes | |||
| -rw-r--r-- | tetris/tetrisc.mid | bin | 0 -> 14661 bytes | 
12 files changed, 1024 insertions, 0 deletions
diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..951a49c --- /dev/null +++ b/README.txt @@ -0,0 +1,28 @@ += some games for palladiumpi with gamepad input = + +pong and tetris from pygames and https://www.101computing.net/pong-tutorial-using-pygame-getting-started/ adapted +to a palladium-pi game device (Palladium TV 500 with black and white screen and Raspbian Raspbery Pi 1 with composite output) + +joystick-input.py used for starting games from the menu and in-game controller +only the first gamepad is used by python inputs library (https://inputs.readthedocs.io/en/latest/user/intro.html) + +select	-> ALT+F4 +start	-> WIN key +A 	-> Return +B 	-> Escape +A+B	-> toggle gamepad as OS input (for using the gamepad inside games or toggling the lxdmenu) + +the script is started using this joystick-input.desktop file in /etc/xdg/autostart +the Path variable is important for python scripts + +""" +[Desktop Entry] +Type=Application +Name=joystick-input +Comment=Joystick input +NoDisplay=true +Exec=/home/pi/src/joystick/joystick-input.py +Path=/home/pi/src/joystick +Terminal=false +Categories=Application; +""" diff --git a/joystick/disable.wav b/joystick/disable.wav Binary files differnew file mode 100644 index 0000000..ef2ddff --- /dev/null +++ b/joystick/disable.wav diff --git a/joystick/enable.wav b/joystick/enable.wav Binary files differnew file mode 100644 index 0000000..2e726b8 --- /dev/null +++ b/joystick/enable.wav diff --git a/joystick/joystick-input.py b/joystick/joystick-input.py new file mode 100755 index 0000000..fb49765 --- /dev/null +++ b/joystick/joystick-input.py @@ -0,0 +1,69 @@ +#!/usr/bin/python3 + +import inputs,os,pygame + +print(inputs.devices.gamepads) + +pads = inputs.devices.gamepads +select=0 +start=0 +disable_pad=False + +pygame.init() +enable=pygame.mixer.Sound('enable.wav') +disable=pygame.mixer.Sound('disable.wav') + +while True: +    events = inputs.get_gamepad() +    for event in events: +        #print(event.ev_type, event.code, event.state) +        if event.code == 'ABS_Y' and event.state == 255: +            #print("down") +            if not disable_pad: +                os.system("xte 'key Down'") +        elif event.code == 'ABS_Y' and event.state == 0: +            #print("up") +            if not disable_pad: +                os.system("xte 'key Up'") +        elif event.code == 'ABS_X' and event.state == 255: +            #print("right") +            if not disable_pad: +                os.system("xte 'key Right'") +        elif event.code == 'ABS_X' and event.state == 0: +            #print("left") +            if not disable_pad: +                os.system("xte 'key Left'") +        elif event.code == 'BTN_TRIGGER' and event.state == 1: +            #print("B") +            if not disable_pad: +                os.system("xte 'key Escape'") +            start=1 +        elif event.code == 'BTN_TRIGGER' and event.state == 0: +            #print("B") +            start=0 +        elif event.code == 'BTN_THUMB' and event.state == 1: +            #print("A") +            if not disable_pad: +                os.system("xte 'key Return'") +            select=1 +        elif event.code == 'BTN_THUMB' and event.state == 0: +            #print("select") +            select=0 +        elif event.code == 'BTN_BASE3' and event.state == 1: +            #print("select") +            if not disable_pad: +                os.system("xte 'keydown Meta_L' 'key F4' 'keyup Meta_L'") +        elif event.code == 'BTN_BASE4' and event.state == 1: +            #print("start") +            if not disable_pad: +                os.system("xte 'key Super_L'") +        if start == 1 and select == 1: +            print("toggle disable pad") +            disable_pad=not disable_pad +            if disable_pad: +                disable.play() +            else: +                enable.play() +            select=0 +            start=0 + diff --git a/joystick/test-joystick.py b/joystick/test-joystick.py new file mode 100755 index 0000000..a8ed6f1 --- /dev/null +++ b/joystick/test-joystick.py @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import pygame + +pygame.display.init() +pygame.joystick.init() + +print ("Joystics: ", pygame.joystick.get_count()) +my_joystick = pygame.joystick.Joystick(0) +my_joystick.init() +clock = pygame.time.Clock() + +print (my_joystick.get_numbuttons()) +print (my_joystick.get_numhats()) +while 1: +    for event in pygame.event.get(): +        print (my_joystick.get_axis(0),  my_joystick.get_axis(1)) +        for i in range(my_joystick.get_numbuttons()): +            print(i, my_joystick.get_button(i)) +        clock.tick(40) + +pygame.quit () diff --git a/pong/Pong.wav b/pong/Pong.wav Binary files differnew file mode 100644 index 0000000..fc00db8 --- /dev/null +++ b/pong/Pong.wav diff --git a/pong/ball.py b/pong/ball.py new file mode 100644 index 0000000..f4e0168 --- /dev/null +++ b/pong/ball.py @@ -0,0 +1,33 @@ +import pygame +from random import randint +  +BLACK = (0, 0, 0) +  +class Ball(pygame.sprite.Sprite): +    #This class represents a car. It derives from the "Sprite" class in Pygame. +     +    def __init__(self, color, width, height): +        # Call the parent class (Sprite) constructor +        super().__init__() +         +        # Pass in the color of the car, and its x and y position, width and height. +        # Set the background color and set it to be transparent +        self.image = pygame.Surface([width, height]) +        self.image.fill(BLACK) +        self.image.set_colorkey(BLACK) +  +        # Draw the ball (a rectangle!) +        pygame.draw.rect(self.image, color, [0, 0, width, height]) +         +        self.velocity = [randint(4,8),randint(-8,8)] +         +        # Fetch the rectangle object that has the dimensions of the image. +        self.rect = self.image.get_rect() +         +    def update(self): +        self.rect.x += self.velocity[0] +        self.rect.y += self.velocity[1] +           +    def bounce(self): +        self.velocity[0] = -self.velocity[0] +        self.velocity[1] = randint(-8,8) diff --git a/pong/paddle.py b/pong/paddle.py new file mode 100644 index 0000000..25dbcbb --- /dev/null +++ b/pong/paddle.py @@ -0,0 +1,33 @@ +import pygame +BLACK = (0,0,0) +  +class Paddle(pygame.sprite.Sprite): +    #This class represents a car. It derives from the "Sprite" class in Pygame. +     +    def __init__(self, color, width, height): +        # Call the parent class (Sprite) constructor +        super().__init__() +         +        # Pass in the color of the car, and its x and y position, width and height. +        # Set the background color and set it to be transparent +        self.image = pygame.Surface([width, height]) +        self.image.fill(BLACK) +        self.image.set_colorkey(BLACK) +  +        # Draw the paddle (a rectangle!) +        pygame.draw.rect(self.image, color, [0, 0, width, height]) +         +        # Fetch the rectangle object that has the dimensions of the image. +        self.rect = self.image.get_rect() +         +    def moveUp(self, pixels): +        self.rect.y -= pixels +        #Check that you are not going too far (off the screen) +        if self.rect.y < 0: +          self.rect.y = 0 +           +    def moveDown(self, pixels): +        self.rect.y += pixels +        #Check that you are not going too far (off the screen) +        if self.rect.y > 480-100: +          self.rect.y = 480-100 diff --git a/pong/pong.py b/pong/pong.py new file mode 100755 index 0000000..0363f3c --- /dev/null +++ b/pong/pong.py @@ -0,0 +1,227 @@ +#!/usr/bin/python3 +# Import the pygame library and initialise the game engine +import pygame, sys +from paddle import Paddle +from ball import Ball +from pygame.locals import * + +# Open a new window was 700x500 +WIDTH=640 +HEIGHT=480 + +#               R    G    B +WHITE       = (255, 255, 255) +GRAY        = (185, 185, 185) +BLACK       = (  0,   0,   0) +RED         = (155,   0,   0) +LIGHTRED    = (175,  20,  20) +GREEN       = (  0, 155,   0) +LIGHTGREEN  = ( 20, 175,  20) +BLUE        = (  0,   0, 155) +LIGHTBLUE   = ( 20,  20, 175) +YELLOW      = (155, 155,   0) +LIGHTYELLOW = (175, 175,  20) + +BORDERCOLOR = BLUE +BGCOLOR = BLACK +TEXTCOLOR = WHITE +TEXTSHADOWCOLOR = GRAY +COLORS      = (     BLUE,      GREEN,      RED,      YELLOW) +LIGHTCOLORS = (LIGHTBLUE, LIGHTGREEN, LIGHTRED, LIGHTYELLOW) +assert len(COLORS) == len(LIGHTCOLORS) # each color must have light color + + +def makeTextObjs(text, font, color): +    surf = font.render(text, True, color) +    return surf, surf.get_rect() + +def terminate(): +    pygame.quit() +    sys.exit() + +def showTextScreen(text): +    # This function displays large text in the +    # center of the screen until a key is pressed. +    # Draw the text drop shadow +    titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTSHADOWCOLOR) +    titleRect.center = (int(WIDTH / 2), int(HEIGHT / 2)) +    screen.blit(titleSurf, titleRect) + +    # Draw the text +    titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTCOLOR) +    titleRect.center = (int(WIDTH / 2) - 3, int(HEIGHT / 2) - 3) +    screen.blit(titleSurf, titleRect) + +    # Draw the additional "Press a key to play." text. +    pressKeySurf, pressKeyRect = makeTextObjs('Press a key to play. \'Select\' to quit. \'B\' to reset.', BASICFONT, TEXTCOLOR) +    pressKeyRect.center = (int(WIDTH / 2), int(HEIGHT / 2) + 100) +    screen.blit(pressKeySurf, pressKeyRect) + +    while checkForKeyPress() == None: +        pygame.display.update() +        clock.tick()  + +def checkForKeyPress(): +    global scoreA, scoreB +    for event in pygame.event.get(): +        if event.type == QUIT:      #event is quit  +            terminate() +        elif event.type == KEYDOWN: +            if event.key == K_ESCAPE:   #event is escape key +                terminate() +            else: +                return event.key   #key found return with it +        elif event.type == JOYBUTTONDOWN or event.type == JOYAXISMOTION: +            if (js1.get_button(8) == 1 or js2.get_button(8) == 1): +                terminate() +            elif (js1.get_button(0) == 1 or js2.get_button(0) == 1): +                scoreA=0 +                scoreB=0 +            return 1 +                                                                                                                                                                     # no quit or key events in queue so return None     +    return None + +def main(): +    global clock, screen, BASICFONT, BIGFONT, js1, js2 +    pygame.init() +    pygame.mouse.set_visible(False) + +    # Define some colors +    BLACK = (0,0,0) +    WHITE = (255,255,255) + +    BASICFONT = pygame.font.Font('freesansbold.ttf', 18) +    BIGFONT = pygame.font.Font('freesansbold.ttf', 100) + +    size = (WIDTH, HEIGHT) +    screen = pygame.display.set_mode(size, FULLSCREEN) +    pygame.display.set_caption("Pong") +    effect=pygame.mixer.Sound('Pong.wav') +      +    #joystick or gamepad init +    pygame.joystick.init() +    print ("Joystics: ", pygame.joystick.get_count()) +    js1 = pygame.joystick.Joystick(0) +    js1.init() +    js2 = pygame.joystick.Joystick(1) +    js2.init() +      +    paddleA = Paddle(WHITE, 10, 100) +    paddleA.rect.x = 20 +    paddleA.rect.y = 200 +      +    paddleB = Paddle(WHITE, 10, 100) +    paddleB.rect.x = WIDTH-30 +    paddleB.rect.y = 200 +      +    ball = Ball(WHITE,10,10) +    ball.rect.x = int(WIDTH/2-5) +    ball.rect.y = 195 +      +    #This will be a list that will contain all the sprites we intend to use in our game. +    all_sprites_list = pygame.sprite.Group() +      +    # Add the car to the list of objects +    all_sprites_list.add(paddleA) +    all_sprites_list.add(paddleB) +    all_sprites_list.add(ball) +      +    # The loop will carry on until the user exit the game (e.g. clicks the close button). +    carryOn = True +      +    # The clock will be used to control how fast the screen updates +    clock = pygame.time.Clock() +      +    #Initialise player scores +    global scoreA, scoreB +    scoreA = 0 +    scoreB = 0 +      +    showTextScreen('Pong') +    # -------- Main Program Loop ----------- +    while carryOn: +        # --- Main event loop +        for event in pygame.event.get(): # User did something +            if event.type == pygame.QUIT: # If user clicked close +                  carryOn = False # Flag that we are done so we exit this loop +            elif event.type==pygame.KEYDOWN: +                    if event.key==pygame.K_x: #Pressing the x Key will quit the game +                         carryOn=False +      +        #Moving the paddles when the use uses the arrow keys (player A) or "W/S" keys (player B)  +        """keys = pygame.key.get_pressed() +        if keys[pygame.K_w]: +            paddleA.moveUp(5) +        if keys[pygame.K_s]: +            paddleA.moveDown(5) +        if keys[pygame.K_UP]: +            paddleB.moveUp(5) +        if keys[pygame.K_DOWN]: +            paddleB.moveDown(5)     +        """ +         +        if js1.get_axis(1) < 0: +            paddleA.moveUp(5) +        if js1.get_axis(1) > 0:	 +            paddleA.moveDown(5) +        if js2.get_axis(1) < 0: +            paddleB.moveUp(5) +        if js2.get_axis(1) > 0:	 +            paddleB.moveDown(5)   +        if (js1.get_button(8) == 1 or js2.get_button(8) == 1): +            terminate() +        if (js1.get_button(9) == 1 or js2.get_button(9) == 1): +            showTextScreen('-Pause-') +             +        # --- Game logic should go here +        all_sprites_list.update() +         +        #Check if the ball is bouncing against any of the 4 walls: +        if ball.rect.x>=WIDTH-10: +            scoreA+=1 +            ball.velocity[0] = -ball.velocity[0] +            effect.play() +        if ball.rect.x<=0: +            scoreB+=1 +            ball.velocity[0] = -ball.velocity[0] +            effect.play() +        if ball.rect.y>HEIGHT-10: +            ball.velocity[1] = -ball.velocity[1] +            effect.play() +        if ball.rect.y<0: +            ball.velocity[1] = -ball.velocity[1]      +            effect.play() +             +        #Detect collisions between the ball and the paddles +        if pygame.sprite.collide_mask(ball, paddleA) or pygame.sprite.collide_mask(ball, paddleB): +          ball.bounce() +          effect.play() +         +        # --- Drawing code should go here +        # First, clear the screen to black.  +        screen.fill(BLACK) +        #Draw the net +        pygame.draw.line(screen, WHITE, [int(WIDTH/2), 0], [int(WIDTH/2), HEIGHT], 5) +         +        #Now let's draw all the sprites in one go. (For now we only have 2 sprites!) +        all_sprites_list.draw(screen)  +      +        #Display scores: +        font = pygame.font.Font(None, 74) +        text = font.render(str(scoreA), 1, WHITE) +        screen.blit(text, (int(WIDTH/2-WIDTH/4),10)) +        text = font.render(str(scoreB), 1, WHITE) +        screen.blit(text, (int(WIDTH/2+WIDTH/4),10)) +      +        # --- Go ahead and update the screen with what we've drawn. +        pygame.display.flip() +          +        # --- Limit to 60 frames per second +        clock.tick(60) +      +    #Once we have exited the main program loop we can stop the game engine: +    pygame.quit() + +if __name__ == '__main__': +    main() + diff --git a/tetris/tetris.py b/tetris/tetris.py new file mode 100755 index 0000000..b03689e --- /dev/null +++ b/tetris/tetris.py @@ -0,0 +1,612 @@ +#!/usr/bin/python3 +# Tetromino (a Tetris clone) +# By Al Sweigart al@inventwithpython.com +# http://inventwithpython.com/pygame +# Released under a "Simplified BSD" license + +# KRT 17/06/2012 rewrite event detection to deal with mouse use +# mods for joystick use by Robert Scheibe 18.06.2020 + +import random, time, pygame, sys +from pygame.locals import * + +#joystick or gamepad init +pygame.joystick.init() +print ("Joystics: ", pygame.joystick.get_count()) +js = pygame.joystick.Joystick(0) +js.init() + + +FPS = 25 +WINDOWWIDTH = 640 +WINDOWHEIGHT = 480 +BOXSIZE = 20 +BOARDWIDTH = 10 +BOARDHEIGHT = 20 +BLANK = '.' + +MOVESIDEWAYSFREQ = 0.15 +MOVEDOWNFREQ = 0.1 + +XMARGIN = int((WINDOWWIDTH - BOARDWIDTH * BOXSIZE) / 2) +TOPMARGIN = WINDOWHEIGHT - (BOARDHEIGHT * BOXSIZE) - 5 + +#               R    G    B +WHITE       = (255, 255, 255) +GRAY        = (185, 185, 185) +GRAY1        = (240, 240, 240) +GRAY2        = (200, 200, 200) +GRAY3        = (160, 160, 160) +GRAY4        = (120, 120, 120) +BLACK       = (  0,   0,   0) +RED         = (155,   0,   0) +LIGHTRED    = (175,  20,  20) +GREEN       = (  0, 155,   0) +LIGHTGREEN  = ( 20, 175,  20) +BLUE        = (  0,   0, 155) +LIGHTBLUE   = ( 20,  20, 175) +YELLOW      = (155, 155,   0) +LIGHTYELLOW = (175, 175,  20) + +BORDERCOLOR = BLUE +BGCOLOR = BLACK +TEXTCOLOR = WHITE +TEXTSHADOWCOLOR = GRAY +#COLORS      = (     BLUE,      GREEN,      RED,      YELLOW) +COLORS      = (     GRAY1,      GRAY2,      GRAY3,      GRAY4) +#LIGHTCOLORS = (LIGHTBLUE, LIGHTGREEN, LIGHTRED, LIGHTYELLOW) +LIGHTCOLORS      = (     GRAY1,      GRAY2,      GRAY3,      GRAY4) +assert len(COLORS) == len(LIGHTCOLORS) # each color must have light color + +#TEMPLATEWIDTH = i, 5 +TEMPLATEWIDTH = 5 +TEMPLATEHEIGHT = 5 + +S_SHAPE_TEMPLATE = [['.....', +                     '.....', +                     '..OO.', +                     '.OO..', +                     '.....'], +                    ['.....', +                     '..O..', +                     '..OO.', +                     '...O.', +                     '.....']] + +Z_SHAPE_TEMPLATE = [['.....', +                     '.....', +                     '.OO..', +                     '..OO.', +                     '.....'], +                    ['.....', +                     '..O..', +                     '.OO..', +                     '.O...', +                     '.....']] + +I_SHAPE_TEMPLATE = [['..O..', +                     '..O..', +                     '..O..', +                     '..O..', +                     '.....'], +                    ['.....', +                     '.....', +                     'OOOO.', +                     '.....', +                     '.....']] + +O_SHAPE_TEMPLATE = [['.....', +                     '.....', +                     '.OO..', +                     '.OO..', +                     '.....']] + +J_SHAPE_TEMPLATE = [['.....', +                     '.O...', +                     '.OOO.', +                     '.....', +                     '.....'], +                    ['.....', +                     '..OO.', +                     '..O..', +                     '..O..', +                     '.....'], +                    ['.....', +                     '.....', +                     '.OOO.', +                     '...O.', +                     '.....'], +                    ['.....', +                     '..O..', +                     '..O..', +                     '.OO..', +                     '.....']] + +L_SHAPE_TEMPLATE = [['.....', +                     '...O.', +                     '.OOO.', +                     '.....', +                     '.....'], +                    ['.....', +                     '..O..', +                     '..O..', +                     '..OO.', +                     '.....'], +                    ['.....', +                     '.....', +                     '.OOO.', +                     '.O...', +                     '.....'], +                    ['.....', +                     '.OO..', +                     '..O..', +                     '..O..', +                     '.....']] + +T_SHAPE_TEMPLATE = [['.....', +                     '..O..', +                     '.OOO.', +                     '.....', +                     '.....'], +                    ['.....', +                     '..O..', +                     '..OO.', +                     '..O..', +                     '.....'], +                    ['.....', +                     '.....', +                     '.OOO.', +                     '..O..', +                     '.....'], +                    ['.....', +                     '..O..', +                     '.OO..', +                     '..O..', +                     '.....']] + +PIECES = {'S': S_SHAPE_TEMPLATE, +          'Z': Z_SHAPE_TEMPLATE, +          'J': J_SHAPE_TEMPLATE, +          'L': L_SHAPE_TEMPLATE, +          'I': I_SHAPE_TEMPLATE, +          'O': O_SHAPE_TEMPLATE, +          'T': T_SHAPE_TEMPLATE} + + +def main(): +    global FPSCLOCK, DISPLAYSURF, BASICFONT, BIGFONT +    pygame.init() +    pygame.mouse.set_visible(False) +     +    FPSCLOCK = pygame.time.Clock() +    #DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT)) +    DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT),FULLSCREEN) +    BASICFONT = pygame.font.Font('freesansbold.ttf', 18) +    BIGFONT = pygame.font.Font('freesansbold.ttf', 100) +    pygame.display.set_caption('Tetromino') + +    showTextScreen('-=TETЯIS=-') +    while True: # game loop +        if random.randint(0, 1) == 0: +            pygame.mixer.music.load('tetrisb.mid') +        else: +            pygame.mixer.music.load('tetrisc.mid') +        pygame.mixer.music.play(-1, 0.0) +        runGame() +        pygame.mixer.music.stop() +        showTextScreen('Game Over') + + +def runGame(): +    # setup variables for the start of the game +    board = getBlankBoard() +    lastMoveDownTime = time.time() +    lastMoveSidewaysTime = time.time() +    lastFallTime = time.time() +    movingDown = False # note: there is no movingUp variable +    movingLeft = False +    movingRight = False +    score = 0 +    level, fallFreq = calculateLevelAndFallFreq(score) + +    fallingPiece = getNewPiece() +    nextPiece = getNewPiece() + +    while True: # game loop +        if fallingPiece == None: +            # No falling piece in play, so start a new piece at the top +            fallingPiece = nextPiece +            nextPiece = getNewPiece() +            lastFallTime = time.time() # reset lastFallTime + +            if not isValidPosition(board, fallingPiece): +                return # can't fit a new piece on the board, so game over + +        checkForQuit() +        for event in pygame.event.get(): # event handling loop +            #key events +            if (event.type == KEYUP ): +                if (event.key == K_p): +                    # Pausing the game +                    DISPLAYSURF.fill(BGCOLOR) +                    pygame.mixer.music.stop() +                    showTextScreen('Paused') # pause until a key press +                    pygame.mixer.music.play(-1, 0.0) +                    lastFallTime = time.time() +                    lastMoveDownTime = time.time() +                    lastMoveSidewaysTime = time.time() +                elif (event.key == K_LEFT or event.key == K_a): +                    movingLeft = False +                elif (event.key == K_RIGHT or event.key == K_d): +                    movingRight = False +                elif (event.key == K_DOWN or event.key == K_s): +                    movingDown = False + +            elif (event.type == KEYDOWN ): +                # moving the piece sideways +                if (event.key == K_LEFT or event.key == K_a and isValidPosition(board, fallingPiece, adjX=-1)): +                    fallingPiece['x'] -= 1 +                    movingLeft = True +                    movingRight = False +                    lastMoveSidewaysTime = time.time() + +                elif (event.key == K_RIGHT or event.key == K_d and isValidPosition(board, fallingPiece, adjX=1)): +                    fallingPiece['x'] += 1 +                    movingRight = True +                    movingLeft = False +                    lastMoveSidewaysTime = time.time() + +                # rotating the piece (if there is room to rotate) +                elif (event.key == K_UP or event.key == K_w ): +                    fallingPiece['rotation'] = (fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']]) +                    if not isValidPosition(board, fallingPiece): +                        fallingPiece['rotation'] = (fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) +                elif (event.key == K_q): # rotate the other direction +                    fallingPiece['rotation'] = (fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) +                    if not isValidPosition(board, fallingPiece): +                        fallingPiece['rotation'] = (fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']]) + +                # making the piece fall faster with the down key +                elif (event.key == K_DOWN or event.key == K_s): +                    movingDown = True +                    if isValidPosition(board, fallingPiece, adjY=1): +                        fallingPiece['y'] += 1 +                    lastMoveDownTime = time.time() + +                # move the current piece all the way down +                elif event.key == K_SPACE: +                    movingDown = False +                    movingLeft = False +                    movingRight = False +                    for i in range(1, BOARDHEIGHT): +                        if not isValidPosition(board, fallingPiece, adjY=i): +                            break +                    fallingPiece['y'] += i - 1 + +            #joystick events +            elif (event.type == JOYBUTTONDOWN): +                if (js.get_button(9) == 1): +                    # Pausing the game +                    DISPLAYSURF.fill(BGCOLOR) +                    pygame.mixer.music.stop() +                    showTextScreen('Paused') # pause until a key press +                    pygame.mixer.music.play(-1, 0.0) +                    lastFallTime = time.time() +                    lastMoveDownTime = time.time() +                    lastMoveSidewaysTime = time.time() + +                # move the current piece all the way down with Button A +                elif (js.get_button(1) == 1): +                    movingDown = False +                    movingLeft = False +                    movingRight = False +                    for i in range(1, BOARDHEIGHT): +                        if not isValidPosition(board, fallingPiece, adjY=i): +                            break +                    fallingPiece['y'] += i - 1 + +                #rotate with button B +                elif (js.get_button(0) == 1): +                    fallingPiece['rotation'] = (fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) +                    if not isValidPosition(board, fallingPiece): +                        fallingPiece['rotation'] = (fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']]) + + +            elif (event.type == JOYAXISMOTION): +                # moving the piece sideways +                if (js.get_axis(0) < 0 and isValidPosition(board, fallingPiece, adjX=-1)): +                    fallingPiece['x'] -= 1 +                    movingLeft = True +                    movingRight = False +                    lastMoveSidewaysTime = time.time() + +                elif ((js.get_axis(0) > 0) and isValidPosition(board, fallingPiece, adjX=1)): +                    fallingPiece['x'] += 1 +                    movingRight = True +                    movingLeft = False +                    lastMoveSidewaysTime = time.time() + +                # rotating the piece (if there is room to rotate) +                elif (js.get_axis(1) < 0): +                    fallingPiece['rotation'] = (fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']]) +                    if not isValidPosition(board, fallingPiece): +                        fallingPiece['rotation'] = (fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) +                #elif (js.get_axis(1) > 0): # rotate the other direction +                #    fallingPiece['rotation'] = (fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']]) +                #    if not isValidPosition(board, fallingPiece): +                #        fallingPiece['rotation'] = (fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']]) + +                # making the piece fall faster with the down key +                elif (js.get_axis(1) > 0): +                    movingDown = True +                    if isValidPosition(board, fallingPiece, adjY=1): +                        fallingPiece['y'] += 1 +                    lastMoveDownTime = time.time() + +                elif (js.get_axis(0)== 0.0): +                    movingLeft = False +                    movingRight = False +                    movingDown = False +  +        # handle moving the piece because of user input +        if (movingLeft or movingRight) and time.time() - lastMoveSidewaysTime > MOVESIDEWAYSFREQ: +            if movingLeft and isValidPosition(board, fallingPiece, adjX=-1): +                fallingPiece['x'] -= 1 +            elif movingRight and isValidPosition(board, fallingPiece, adjX=1): +                fallingPiece['x'] += 1 +            lastMoveSidewaysTime = time.time() + +        if movingDown and time.time() - lastMoveDownTime > MOVEDOWNFREQ and isValidPosition(board, fallingPiece, adjY=1): +            fallingPiece['y'] += 1 +            lastMoveDownTime = time.time() + +        # let the piece fall if it is time to fall +        if time.time() - lastFallTime > fallFreq: +            # see if the piece has landed +            if not isValidPosition(board, fallingPiece, adjY=1): +                # falling piece has landed, set it on the board +                addToBoard(board, fallingPiece) +                score += removeCompleteLines(board) +                level, fallFreq = calculateLevelAndFallFreq(score) +                fallingPiece = None +            else: +                # piece did not land, just move the piece down +                fallingPiece['y'] += 1 +                lastFallTime = time.time() + +        # drawing everything on the screen +        DISPLAYSURF.fill(BGCOLOR) +        drawBoard(board) +        drawStatus(score, level) +        drawNextPiece(nextPiece) +        if fallingPiece != None: +            drawPiece(fallingPiece) + +        pygame.display.update() +        FPSCLOCK.tick(FPS) + + +def makeTextObjs(text, font, color): +    surf = font.render(text, True, color) +    return surf, surf.get_rect() + + +def terminate(): +    pygame.quit() +    sys.exit() + + +# KRT 17/06/2012 rewrite event detection to deal with mouse use +def checkForKeyPress(): +    for event in pygame.event.get(): +        if event.type == QUIT:      #event is quit  +            terminate() +        elif event.type == KEYDOWN: +            if event.key == K_ESCAPE:   #event is escape key +                terminate() +            else: +                return event.key   #key found return with it +        elif event.type == JOYBUTTONDOWN or event.type == JOYAXISMOTION: +            if (js.get_button(8) == 1): +                terminate() +            return 1 +    # no quit or key events in queue so return None     +    return None + + + +##def checkForKeyPress(): +##    # Go through event queue looking for a KEYUP event. +##    # Grab KEYDOWN events to remove them from the event queue. +##    checkForQuit() +## +##    for event in pygame.event.get([KEYDOWN, KEYUP]): +##        if event.type == KEYDOWN: +##            continue +##        return event.key +##    return None + + +def showTextScreen(text): +    # This function displays large text in the +    # center of the screen until a key is pressed. +    # Draw the text drop shadow +    titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTSHADOWCOLOR) +    titleRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2)) +    DISPLAYSURF.blit(titleSurf, titleRect) + +    # Draw the text +    titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTCOLOR) +    titleRect.center = (int(WINDOWWIDTH / 2) - 3, int(WINDOWHEIGHT / 2) - 3) +    DISPLAYSURF.blit(titleSurf, titleRect) + +    # Draw the additional "Press a key to play." text. +    pressKeySurf, pressKeyRect = makeTextObjs('Press a key to play. \'Select\' to quit.', BASICFONT, TEXTCOLOR) +    pressKeyRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 100) +    DISPLAYSURF.blit(pressKeySurf, pressKeyRect) + +    while checkForKeyPress() == None: +        pygame.display.update() +        FPSCLOCK.tick() + + +def checkForQuit(): +    for event in pygame.event.get(QUIT): # get all the QUIT events +        terminate() # terminate if any QUIT events are present +    for event in pygame.event.get(KEYUP): # get all the KEYUP events +        if event.key == K_ESCAPE: +            terminate() # terminate if the KEYUP event was for the Esc key +        pygame.event.post(event) # put the other KEYUP event objects back + + +def calculateLevelAndFallFreq(score): +    # Based on the score, return the level the player is on and +    # how many seconds pass until a falling piece falls one space. +    level = int(score / 10) + 1 +    fallFreq = 0.27 - (level * 0.02) +    return level, fallFreq + +def getNewPiece(): +    # return a random new piece in a random rotation and color +    shape = random.choice(list(PIECES.keys())) +    newPiece = {'shape': shape, +                'rotation': random.randint(0, len(PIECES[shape]) - 1), +                'x': int(BOARDWIDTH / 2) - int(TEMPLATEWIDTH / 2), +                'y': -2, # start it above the board (i.e. less than 0) +                'color': random.randint(0, len(COLORS)-1)} +    return newPiece + + +def addToBoard(board, piece): +    # fill in the board based on piece's location, shape, and rotation +    for x in range(TEMPLATEWIDTH): +        for y in range(TEMPLATEHEIGHT): +            if PIECES[piece['shape']][piece['rotation']][y][x] != BLANK: +                board[x + piece['x']][y + piece['y']] = piece['color'] + + +def getBlankBoard(): +    # create and return a new blank board data structure +    board = [] +    for i in range(BOARDWIDTH): +        board.append([BLANK] * BOARDHEIGHT) +    return board + + +def isOnBoard(x, y): +    return x >= 0 and x < BOARDWIDTH and y < BOARDHEIGHT + + +def isValidPosition(board, piece, adjX=0, adjY=0): +    # Return True if the piece is within the board and not colliding +    for x in range(TEMPLATEWIDTH): +        for y in range(TEMPLATEHEIGHT): +            isAboveBoard = y + piece['y'] + adjY < 0 +            if isAboveBoard or PIECES[piece['shape']][piece['rotation']][y][x] == BLANK: +                continue +            if not isOnBoard(x + piece['x'] + adjX, y + piece['y'] + adjY): +                return False +            if board[x + piece['x'] + adjX][y + piece['y'] + adjY] != BLANK: +                return False +    return True + +def isCompleteLine(board, y): +    # Return True if the line filled with boxes with no gaps. +    for x in range(BOARDWIDTH): +        if board[x][y] == BLANK: +            return False +    return True + + +def removeCompleteLines(board): +    # Remove any completed lines on the board, move everything above them down, and return the number of complete lines. +    numLinesRemoved = 0 +    y = BOARDHEIGHT - 1 # start y at the bottom of the board +    while y >= 0: +        if isCompleteLine(board, y): +            # Remove the line and pull boxes down by one line. +            for pullDownY in range(y, 0, -1): +                for x in range(BOARDWIDTH): +                    board[x][pullDownY] = board[x][pullDownY-1] +            # Set very top line to blank. +            for x in range(BOARDWIDTH): +                board[x][0] = BLANK +            numLinesRemoved += 1 +            # Note on the next iteration of the loop, y is the same. +            # This is so that if the line that was pulled down is also +            # complete, it will be removed. +        else: +            y -= 1 # move on to check next row up +    return numLinesRemoved + + +def convertToPixelCoords(boxx, boxy): +    # Convert the given xy coordinates of the board to xy +    # coordinates of the location on the screen. +    return (XMARGIN + (boxx * BOXSIZE)), (TOPMARGIN + (boxy * BOXSIZE)) + + +def drawBox(boxx, boxy, color, pixelx=None, pixely=None): +    # draw a single box (each tetromino piece has four boxes) +    # at xy coordinates on the board. Or, if pixelx & pixely +    # are specified, draw to the pixel coordinates stored in +    # pixelx & pixely (this is used for the "Next" piece). +    if color == BLANK: +        return +    if pixelx == None and pixely == None: +        pixelx, pixely = convertToPixelCoords(boxx, boxy) +    pygame.draw.rect(DISPLAYSURF, COLORS[color], (pixelx + 1, pixely + 1, BOXSIZE - 1, BOXSIZE - 1)) +    pygame.draw.rect(DISPLAYSURF, LIGHTCOLORS[color], (pixelx + 1, pixely + 1, BOXSIZE - 4, BOXSIZE - 4)) + + +def drawBoard(board): +    # draw the border around the board +    pygame.draw.rect(DISPLAYSURF, BORDERCOLOR, (XMARGIN - 3, TOPMARGIN - 7, (BOARDWIDTH * BOXSIZE) + 8, (BOARDHEIGHT * BOXSIZE) + 8), 5) + +    # fill the background of the board +    pygame.draw.rect(DISPLAYSURF, BGCOLOR, (XMARGIN, TOPMARGIN, BOXSIZE * BOARDWIDTH, BOXSIZE * BOARDHEIGHT)) +    # draw the individual boxes on the board +    for x in range(BOARDWIDTH): +        for y in range(BOARDHEIGHT): +            drawBox(x, y, board[x][y]) + + +def drawStatus(score, level): +    # draw the score text +    scoreSurf = BASICFONT.render('Score: %s' % score, True, TEXTCOLOR) +    scoreRect = scoreSurf.get_rect() +    scoreRect.topleft = (WINDOWWIDTH - 150, 20) +    DISPLAYSURF.blit(scoreSurf, scoreRect) + +    # draw the level text +    levelSurf = BASICFONT.render('Level: %s' % level, True, TEXTCOLOR) +    levelRect = levelSurf.get_rect() +    levelRect.topleft = (WINDOWWIDTH - 150, 50) +    DISPLAYSURF.blit(levelSurf, levelRect) + + +def drawPiece(piece, pixelx=None, pixely=None): +    shapeToDraw = PIECES[piece['shape']][piece['rotation']] +    if pixelx == None and pixely == None: +        # if pixelx & pixely hasn't been specified, use the location stored in the piece data structure +        pixelx, pixely = convertToPixelCoords(piece['x'], piece['y']) + +    # draw each of the boxes that make up the piece +    for x in range(TEMPLATEWIDTH): +        for y in range(TEMPLATEHEIGHT): +            if shapeToDraw[y][x] != BLANK: +                drawBox(None, None, piece['color'], pixelx + (x * BOXSIZE), pixely + (y * BOXSIZE)) + + +def drawNextPiece(piece): +    # draw the "next" text +    nextSurf = BASICFONT.render('Next:', True, TEXTCOLOR) +    nextRect = nextSurf.get_rect() +    nextRect.topleft = (WINDOWWIDTH - 120, 80) +    DISPLAYSURF.blit(nextSurf, nextRect) +    # draw the "next" piece +    drawPiece(piece, pixelx=WINDOWWIDTH-120, pixely=100) + + +if __name__ == '__main__': +    main() diff --git a/tetris/tetrisb.mid b/tetris/tetrisb.mid Binary files differnew file mode 100644 index 0000000..04a78d9 --- /dev/null +++ b/tetris/tetrisb.mid diff --git a/tetris/tetrisc.mid b/tetris/tetrisc.mid Binary files differnew file mode 100644 index 0000000..24a57bd --- /dev/null +++ b/tetris/tetrisc.mid  | 
