summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.txt28
-rw-r--r--joystick/disable.wavbin0 -> 419318 bytes
-rw-r--r--joystick/enable.wavbin0 -> 418996 bytes
-rwxr-xr-xjoystick/joystick-input.py69
-rwxr-xr-xjoystick/test-joystick.py22
-rw-r--r--pong/Pong.wavbin0 -> 23292 bytes
-rw-r--r--pong/ball.py33
-rw-r--r--pong/paddle.py33
-rwxr-xr-xpong/pong.py227
-rwxr-xr-xtetris/tetris.py612
-rw-r--r--tetris/tetrisb.midbin0 -> 8612 bytes
-rw-r--r--tetris/tetrisc.midbin0 -> 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
new file mode 100644
index 0000000..ef2ddff
--- /dev/null
+++ b/joystick/disable.wav
Binary files differ
diff --git a/joystick/enable.wav b/joystick/enable.wav
new file mode 100644
index 0000000..2e726b8
--- /dev/null
+++ b/joystick/enable.wav
Binary files differ
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
new file mode 100644
index 0000000..fc00db8
--- /dev/null
+++ b/pong/Pong.wav
Binary files differ
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
new file mode 100644
index 0000000..04a78d9
--- /dev/null
+++ b/tetris/tetrisb.mid
Binary files differ
diff --git a/tetris/tetrisc.mid b/tetris/tetrisc.mid
new file mode 100644
index 0000000..24a57bd
--- /dev/null
+++ b/tetris/tetrisc.mid
Binary files differ