0 likes | 15 Views
Have you ever played the Tetris puzzle? It is a video game that is developed with a motive to get an order out of chaos. It helps in improving both thinking and learning skills. Wouldnu2019t it be interesting to build this game in Python? So, letu2019s start.<br>
E N D
Python Tetris Game – Develop Tetris using PyGame
Have you ever played the Tetris puzzle? It is a video game that is developed with a motive to get an order out of chaos. It helps in improving both thinking and learning skills. Wouldn’t it be interesting to build this game in Python? So, let’s start. What is Tetris? The Tetris game consists of blocks/tetriminos, of different shapes. that appear one after another. And the objective is to place these blocks on the screen such that we form rows at the bottom of the board. Every completed row increases the score. To do so, the player will be allowed to move the falling block to left, right, down and also rotate it using the keyboard buttons. Python Tetris – Project details To build this game we will be using the Pygame module in Python. We will also use the random module to select the shape and color of the Tetrimino. And we consider the whole game board and the blocks as matrices. This makes it easy to do the operations, shifting, and rotation. Download Python Tetris Code Please download the code for the Tetris game here: Python Tetris Game Project Source Code
Project Prerequisites It is suggested to have prior knowledge on Python and PyGame. If you don’t have the PyGame module, then you can install it using the following command. pip install pygame Steps to build the Python Tetris Game We are done discussing the necessities of the project, let us look into the steps to be followed to build the project. 1. Create a matrix storing the information about the block and write a class to handle these details. 2. Create a class to handle the creation of blocks, their movement, and placement. 3. Create the main window for the game. 4. Keep checking the button pressed and the status of the blocks in the board. 5. End the game when the blocks touch the top of the board. This game is written in an infinite while loop that runs till the fifth condition above is met. 1. Importing the required modules
We are importing the pygame module which we use to build the Tetris game and then importing the random module to get the shapes of the blocks in a random manner. import pygame import random 2. Creating variables to store shapes and colors of the blocks In the below code, the shapes variable holds the matrix that contains information about the shape of the block. Assume a 4×4 block and give each cell indices as shown below 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Then, [1, 5, 9, 13] represents the vertical line (second column), [1, 5, 9, 8] represents L shape, etc. And the shapeColors hold the RGB values of different colors from which we randomly select a color for a block. #Shapes of the blocks shapes = [
[[1, 5, 9, 13], [4, 5, 6, 7]], [[4, 5, 9, 10], [2, 6, 5, 9]], [[6, 7, 9, 10], [1, 5, 6, 10]], [[1, 2, 5, 9], [0, 4, 5, 6], [1, 5, 9, 8], [4, 5, 6, 10]], [[1, 2, 6, 10], [5, 6, 7, 9], [2, 6, 10, 11], [3, 5, 6, 7]], [[1, 4, 5, 6], [1, 4, 5, 9], [4, 5, 6, 9], [1, 5, 6, 9]], [[1, 2, 5, 6]], ] #Colors of the blocks shapeColors = [(0, 255, 0), (255, 0, 0), (0, 255, 255), (255, 255, 0), (255, 165, 0), (0, 0, 255), (128, 0, 128)] 3. Creating a class Blocks to hold information about the current block This class assigns the coordinates, shape, color and rotation to the block object created. Using the function random.randint(), which generates a random integer in the given range, a random shape and color are assigned to a block. The function rotate() gives the index of the rotation variant of a given shape from the matrix ‘shapes’. And the function image() returns the rotated variant block to the Block object. # GLOBALS VARS width = 700 height = 600
gameWidth = 100 gameHeight = 400 blockSize = 20 topLeft_x = (width - gameWidth) // 2 topLeft_y = height - gameHeight - 50 class Block: x = 0 y = 0 n = 0 def __init__(self, x, y,n): self.x = x self.y = y self.type = n self.color = n self.rotation = 0 def image(self): return shapes[self.type][self.rotation] def rotate(self): self.rotation = (self.rotation + 1) % len(shapes[self.type])
4. Creating a class Tetris for creation of blocks, controlling their movement and placement In this class, we first create variables that set the properties of the board and also set the score to 0 and state to “start”. The field variable stores the board in the form of a 2D matrix. # GLOBALS VARS width = 700 height = 600 gameWidth = 100 gameHeight = 400 blockSize = 20 topLeft_x = (width - gameWidth) // 2 topLeft_y = height - gameHeight - 50 class Block: x = 0 y = 0 n = 0 def __init__(self, x, y,n): self.x = x self.y = y
self.type = n self.color = n self.rotation = 0 def image(self): return shapes[self.type][self.rotation] def rotate(self): self.rotation = (self.rotation + 1) % len(shapes[self.type]) In the following code, which is a part of the Tetris class, has the below functions 1. The new_block() function creates a new block using the Block() class. 2. The function next_block() creates the next block that would be appearing on the screen. 3. The intersects() function checks if the blocks touch the top of the board. This decides the end of the game. 4. The break_lines() function checks if the blocks form any row. If the condition is met, then it increases the score and deletes the line. 5. And the function draw_next_block() places the next block beside the main game to show it to the player. #Creates a new block def new_block(self): self.block = Block(3, 0,random.randint(0, len(shapes) - 1))
def next_block(self): self.nextBlock=Block(3,0,random.randint(0, len(shapes) - 1)) #Checks if the blocks touch the top of the board def intersects(self): intersection = False for i in range(4): for j in range(4): if i * 4 + j in self.block.image(): if i + self.block.y > self.height - 1 or \ j + self.block.x > self.width - 1 or \ j + self.block.x < 0 or \ self.field[i + self.block.y][j + self.block.x] > 0: intersection = True return intersection #Checks if a row is formed and destroys that line def break_lines(self): lines = 0 for i in range(1, self.height): zeros = 0 for j in range(self.width): if self.field[i][j] == 0:
zeros += 1 if zeros == 0: lines += 1 for i1 in range(i, 1, -1): for j in range(self.width): self.field[i1][j] = self.field[i1 - 1][j] self.score += lines ** 2 def draw_next_block(self,screen): font = pygame.font.SysFont("Calibri", 30) label = font.render("Next Shape", 1, (128,128,128)) sx = topLeft_x + gameWidth + 50 sy = topLeft_y + gameHeight/2 - 100 format = self.nextBlock.image() for i in range(4): for j in range(4): p = i * 4 + j if p in self.nextBlock.image(): pygame.draw.rect(screen, shapeColors[self.nextBlock.color],(sx + j*30, sy + i*30, 30, 30), 0) Now it’s time to write the functions to move the blocks. 1. The go_down() function moves the block down by a unit
2. The go_space() function is similar to go_down(), but it moves the block down to the bottom 3. The freez() function runs once the block reaches the bottom. And it checks if any row is formed, forms a new block and if it touches the top, it ends the game. 4. The go_side() function moves the block to either right or left 5. And the rotate() function rotates the block by 90 degrees in clockwise or anticlockwise direction #Moves the block down by a unit def go_down(self): self.block.y += 1 if self.intersects(): self.block.y -= 1 self.freeze() #Moves the block to the bottom def go_space(self): while not self.intersects(): self.block.y += 1 self.block.y -= 1 self.freeze() # This function runs once the block reaches the bottom.
def freeze(self): for i in range(4): for j in range(4): if i * 4 + j in self.block.image(): self.field[i + self.block.y][j + self.block.x] = self.block.color self.break_lines() #Checking if any row is formed self.new_block() #Creating a new block if self.intersects(): #If blocks touch the top of the board, then ending the game by setting status as gameover self.state = "gameover" #This function moves the block horizontally def go_side(self, dx): old_x = self.block.x self.block.x += dx if self.intersects(): self.block.x = old_x #This function rotates the block def rotate(self): old_rotation = self.block.rotation self.block.rotate() if self.intersects(): self.block.rotation = old_rotation
Main game It’s time to create the main window. We do this by using the init() function in PyGame. We also set the other properties like size, and title. When the user presses any of the keyboard buttons, the main game starts. pygame.font.init() screen = pygame.display.set_mode((width, height)) pygame.display.set_caption("Tetris by DataFlair") run = True while run: screen.fill((16, 57, 34 )) font = pygame.font.SysFont("Calibri", 70, bold=True) label = font.render("Press any key to begin!", True, '#FFFFFF') screen.blit(label, (10, 300 )) pygame.display.update() for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if event.type == pygame.KEYDOWN: startGame() pygame.quit()
Now, write the function startGame() with a for loop that runs infinitely till the game end condition is met. This loop includes the following operations: 1. Creating a new block if there is no moving block. 2. Moving the block down by a unit continuously or when the down key is pressed. 3. Checking the key pressed, if any, and doing the corresponding function discussed above. 4. Updating the board with the previous blocks and the moving block. 5. Checking the status and ending the game if the status is gameover def startGame(): done = False clock = pygame.time.Clock() fps = 25 game = Tetris(20, 10) counter = 0 pressing_down = False while not done: #Create a new block if there is no moving block if game.block is None:
game.new_block() if game.nextBlock is None: game.next_block() counter += 1 #Keeping track of the time if counter > 100000: counter = 0 #Moving the block continuously with time or when down key is pressed if counter % (fps // game.level // 2) == 0 or pressing_down: if game.state == "start": game.go_down() #Checking which key is pressed and running corresponding function for event in pygame.event.get(): if event.type == pygame.QUIT: done = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: game.rotate() if event.key == pygame.K_DOWN: game.moveDown() if event.key == pygame.K_LEFT: game.moveHoriz(-1) if event.key == pygame.K_RIGHT:
game.moveHoriz(1) if event.key == pygame.K_SPACE: game.moveBottom() if event.key == pygame.K_ESCAPE: game.__init__(20, 10) screen.fill('#FFFFFF') #Updating the game board regularly for i in range(game.height): for j in range(game.width): pygame.draw.rect(screen, '#B2BEB5', [game.x + game.zoom * j, game.y + game.zoom * i, game.zoom, game.zoom], 1) if game.field[i][j] > 0: pygame.draw.rect(screen, shapeColors[game.field[i][j]], [game.x + game.zoom * j + 1, game.y + game.zoom * i + 1, game.zoom - 2, game.zoom - 1]) #Updating the board with the moving block if game.block is not None: for i in range(4): for j in range(4): p = i * 4 + j if p in game.block.image(): pygame.draw.rect(screen, shapeColors[game.block.color],
[game.x + game.zoom * (j + game.block.x) + 1, game.y + game.zoom * (i + game.block.y) + 1, game.zoom - 2, game.zoom - 2]) #Showing the score font = pygame.font.SysFont('Calibri', 40, True, False) font1 = pygame.font.SysFont('Calibri', 25, True, False) text = font.render("Score: " + str(game.score), True, '#000000') text_game_over = font.render("Game Over", True, '#000000') text_game_over1 = font.render("Press ESC", True, '#000000') #Ending the game if state is gameover screen.blit(text, [300, 0]) if game.state == "gameover": screen.blit(text_game_over, [300, 200]) screen.blit(text_game_over1, [300, 265]) game.draw_next_block(screen) pygame.display.flip() clock.tick(fps) Python Tetris Game Output
Summary With this Python project, we have successfully built the python tetris game. For this, we used the pygame and random libraries. We learned how to create shapes for blocks, capture events from the keyboard and trigger a function. We could also check the status of the Tetris board. Hoping that you enjoyed developing this with us! Free Python course with 57 real-time projects - Learn Python in Hindi | Learn Python in English