Movatterモバイル変換


[0]ホーム

URL:


How to Make a Tetris Game using PyGame in Python

Master the creation of a classic Tetris game using Pygame with this step-by-step tutorial. Learn to handle game logic, user input, and rendering while building your own customizable Tetris clone in Python.
  · 9 min read · Updated may 2023 ·Game Development

Struggling with multiple programming languages? No worries. OurCode Converter has got you covered. Give it a go!

Tetris is a classic puzzle game where the objective is to arrange falling geometric pieces, called tetrominoes, to fill horizontal lines without leaving gaps. When a line is completely filled, it is cleared, and the player earns points. The game becomes progressively more challenging as the tetrominoes fall faster, making it harder to arrange them in time.

In this tutorial, we will walk you through the process of creating a simple Tetris game step by step usingPyGame. We will cover the following topics:

  • Setting up the development environment and installing Pygame
  • Creating the game window and defining Tetris pieces
  • Implementing the Tetromino and Tetris classes to manage game logic
  • Handling user input and game events
  • Drawing the game state, score, and game over messages on the screen
  • Implementing the main game loop

By the end of this tutorial, you will have a fully functional Tetris game that you can play and customize. This project will also help you understand the basics of game development with Python and Pygame and serve as a foundation for creating other types of games. Here's how it'll look like:

Simple Tetris game with Pygame

Table of content:

Getting Started

Once you have Python installed, open your terminal or command prompt and enter the following command to install the Pygame library:

$ pip install pygame

Creating the Game Window

Now that our development environment is ready, let's start by creating the game window and defining the tetromino shapes.

First, we need to import the necessary modules for our Tetris game. Add the following lines to your Python script:

import sysimport pygameimport random

To use the Pygame library, we need to initialize it. Add the following line after the import statements:

pygame.init()

Defining Screen Dimensions, Colors, and Tetromino Shapes

Next, we need to define some constants for our game, such as screen dimensions, grid size, colors, and the shapes of the tetrominoes. Add the following lines to your script:

# Screen dimensionsWIDTH, HEIGHT = 800, 600GRID_SIZE = 25# ColorsWHITE = (255, 255, 255)BLACK = (0, 0, 0)RED = (255, 0, 0)BLUE = (0, 0, 255)GREEN = (0, 255, 0)COLORS = [RED, BLUE, GREEN]# Tetromino shapesSHAPES = [    [        ['.....',         '.....',         '.....',         'OOOO.',         '.....'],        ['.....',         '..O..',         '..O..',         '..O..',         '..O..']    ],    [        ['.....',         '.....',         '..O..',         '.OOO.',         '.....'],        ['.....',         '..O..',         '.OO..',         '..O..',         '.....'],        ['.....',         '.....',         '.OOO.',         '..O..',         '.....'],        ['.....',         '..O..',         '..OO.',         '..O..',         '.....']    ],    [        [         '.....',         '.....',         '..OO.',         '.OO..',         '.....'],        ['.....',         '.....',         '.OO..',         '..OO.',         '.....'],        ['.....',         '.O...',         '.OO..',         '..O..',         '.....'],        ['.....',         '..O..',         '.OO..',         '.O...',         '.....']    ],    [        ['.....',         '..O..',         '..O.',         '..OO.',         '.....'],        ['.....',         '...O.',         '.OOO.',         '.....',         '.....'],        ['.....',         '.OO..',         '..O..',         '..O..',         '.....'],        ['.....',         '.....',         '.OOO.',         '.O...',         '.....']    ],]

Here, we define the width and height of the game window, the grid size for the tetrominoes, and the colors we will use for the game (white, black, and red). TheSHAPES list contains the tetromino shapes represented as strings, you're free to add/edit as you wish. You can also play around with the colors and grid size.

Implementing theTetromino andTetris Classes to Manage Game Logic

Now that we have our game window and tetromino shapes defined, let's create two classes to manage the game logic: the Tetromino class and the Tetris class.

Creating theTetromino Class

TheTetromino class will represent a single tetromino piece, with properties for its position,shape,color, androtation. Add the following code to your script:

class Tetromino:    def __init__(self, x, y, shape):        self.x = x        self.y = y        self.shape = shape        self.color = random.choice(COLORS) # You can choose different colors for each shape        self.rotation = 0

Creating theTetris Class

TheTetris class will handle the main game logic. It will have methods for creating a new piece, checking if a move is valid, clearing lines, locking a piece, updating the game state, and drawing the game. Add the following code to your script:

class Tetris:    def __init__(self, width, height):        self.width = width        self.height = height        self.grid = [[0 for _ in range(width)] for _ in range(height)]        self.current_piece = self.new_piece()        self.game_over = False        self.score = 0  # Add score attribute

Let's make a method for making a newTetromino piece:

    def new_piece(self):        # Choose a random shape        shape = random.choice(SHAPES)        # Return a new Tetromino object        return Tetromino(self.width // 2, 0, shape)

Next, thevalid_move() method checks whether a piece can move to the given position:

    def valid_move(self, piece, x, y, rotation):        """Check if the piece can move to the given position"""        for i, row in enumerate(piece.shape[(piece.rotation + rotation) % len(piece.shape)]):            for j, cell in enumerate(row):                try:                    if cell == 'O' and (self.grid[piece.y + i + y][piece.x + j + x] != 0):                        return False                except IndexError:                    return False        return True

Theclear_lines() method clears the lines that are full and returns the number of cleared lines so we can calculate the score later:

    def clear_lines(self):        """Clear the lines that are full and return the number of cleared lines"""        lines_cleared = 0        for i, row in enumerate(self.grid[:-1]):            if all(cell != 0 for cell in row):                lines_cleared += 1                del self.grid[i]                self.grid.insert(0, [0 for _ in range(self.width)])        return lines_cleared

Now the method for locking the pieces:

    def lock_piece(self, piece):        """Lock the piece in place and create a new piece"""        for i, row in enumerate(piece.shape[piece.rotation % len(piece.shape)]):            for j, cell in enumerate(row):                if cell == 'O':                    self.grid[piece.y + i][piece.x + j] = piece.color        # Clear the lines and update the score        lines_cleared = self.clear_lines()        self.score += lines_cleared * 100  # Update the score based on the number of cleared lines        # Create a new piece        self.current_piece = self.new_piece()        # Check if the game is over        if not self.valid_move(self.current_piece, 0, 0, 0):            self.game_over = True        return lines_cleared

Theupdate() function to move the tetromino one cell down:

    def update(self):        """Move the tetromino down one cell"""        if not self.game_over:            if self.valid_move(self.current_piece, 0, 1, 0):                self.current_piece.y += 1            else:                self.lock_piece(self.current_piece)

Finally, we make the method for drawing the game grid and the current piece:

    def draw(self, screen):        """Draw the grid and the current piece"""        for y, row in enumerate(self.grid):            for x, cell in enumerate(row):                if cell:                    pygame.draw.rect(screen, cell, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1))        if self.current_piece:            for i, row in enumerate(self.current_piece.shape[self.current_piece.rotation % len(self.current_piece.shape)]):                for j, cell in enumerate(row):                    if cell == 'O':                        pygame.draw.rect(screen, self.current_piece.color, ((self.current_piece.x + j) * GRID_SIZE, (self.current_piece.y + i) * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1))

Creating Helper Functions for Drawing Text in the Game

Now that we've made theTetris class, let's make two helper functions that draw text, one for the score, and another for the "Game Over!":

def draw_score(screen, score, x, y):    """Draw the score on the screen"""    font = pygame.font.Font(None, 36)    text = font.render(f"Score: {score}", True, WHITE)    screen.blit(text, (x, y))        def draw_game_over(screen, x, y):    """Draw the game over text on the screen"""    font = pygame.font.Font(None, 48)    text = font.render("Game Over", True, RED)    screen.blit(text, (x, y))

These functions take four arguments (three in the case ofdraw_game_over()):

  • screen: the Pygame surface to draw on.
  • score: the current game score.
  • x: the x-coordinate of the position where the score will be displayed.
  • y: the y-coordinate of the position where the score will be displayed.

The functions create a font object usingpygame.font.Font(None, 36), render the score text with thefont.render() method, and then usescreen.blit() to display the text on the screen.

Making the Game Loop

Before running the loop, we start by initializing Pygame, creating the clock object, and creating the game screen and the game, theTetris object:

def main():    # Initialize pygame    screen = pygame.display.set_mode((WIDTH, HEIGHT))    pygame.display.set_caption('Tetris')    # Create a clock object    clock = pygame.time.Clock()    # Create a Tetris object    game = Tetris(WIDTH // GRID_SIZE, HEIGHT // GRID_SIZE)    fall_time = 0    fall_speed = 50  # You can adjust this value to change the falling speed, it's in milliseconds

You can adjust thefall_speed to lower it (make it faster), or increase it to make it slower.

Here's the game loop:

    while True:        # Fill the screen with black        screen.fill(BLACK)         for event in pygame.event.get():            # Check for the QUIT event            if event.type == pygame.QUIT:                pygame.quit()                sys.exit()            # Check for the KEYDOWN event            if event.type == pygame.KEYDOWN:                if event.key == pygame.K_LEFT:                    if game.valid_move(game.current_piece, -1, 0, 0):                        game.current_piece.x -= 1 # Move the piece to the left                if event.key == pygame.K_RIGHT:                    if game.valid_move(game.current_piece, 1, 0, 0):                        game.current_piece.x += 1 # Move the piece to the right                if event.key == pygame.K_DOWN:                    if game.valid_move(game.current_piece, 0, 1, 0):                        game.current_piece.y += 1 # Move the piece down                if event.key == pygame.K_UP:                    if game.valid_move(game.current_piece, 0, 0, 1):                        game.current_piece.rotation += 1 # Rotate the piece                if event.key == pygame.K_SPACE:                    while game.valid_move(game.current_piece, 0, 1, 0):                        game.current_piece.y += 1 # Move the piece down until it hits the bottom                    game.lock_piece(game.current_piece) # Lock the piece in place        # Get the number of milliseconds since the last frame        delta_time = clock.get_rawtime()         # Add the delta time to the fall time        fall_time += delta_time         if fall_time >= fall_speed:            # Move the piece down            game.update()            # Reset the fall time            fall_time = 0        # Draw the score on the screen        draw_score(screen, game.score, 10, 10)        # Draw the grid and the current piece        game.draw(screen)        if game.game_over:            # Draw the "Game Over" message            draw_game_over(screen, WIDTH // 2 - 100, HEIGHT // 2 - 30)  # Draw the "Game Over" message            # You can add a "Press any key to restart" message here            # Check for the KEYDOWN event            if event.type == pygame.KEYDOWN:                # Create a new Tetris object                game = Tetris(WIDTH // GRID_SIZE, HEIGHT // GRID_SIZE)        # Update the display        pygame.display.flip()        # Set the framerate        clock.tick(60)

The main game loop is awhile loop that continuously executes the following steps:

  1. Clear the screen by filling it with black.
  2. Process Pygame events, such as quitting the game or handling keyboard input for moving and rotating the Tetris pieces.
  3. Update the game state, including moving the current piece down by one row and locking the piece in place when it reaches the bottom.
  4. Draw the current score, the game grid, and the current piece on the screen.
  5. Display the "Game Over" message if the game is over.
  6. Update the Pygame display and control the frame rate with the clock object.

Final Words

That's it! This simple implementation of a Tetris game should now be functional. You can run the script to play the game and make any desired customizations to the gameplay, graphics, or controls.

You can getthe complete code here.

Here are some related games built with Python:

Happy coding ♥

Found the article interesting? You'll love ourPython Code Generator! Give AI a chance to do the heavy lifting for you. Check it out!

View Full Code Transform My Code
Sharing is caring!



Read Also


How to Create a Hangman Game using PyGame in Python
How to Make a Chess Game with Pygame in Python
How to Make a Drawing Program in Python

Comment panel

    Got a coding query or need some guidance before you comment? Check out thisPython Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!





    Ethical Hacking with Python EBook - Topic - Top


    Join 50,000+ Python Programmers & Enthusiasts like you!



    Tags


    New Tutorials

    Popular Tutorials


    Ethical Hacking with Python EBook - Topic - Bottom

    CodingFleet - Topic - Bottom






    Claim your Free Chapter!

    Download a Completely Free Practical Python PDF Processing Chapter.

    See how the book can help you build handy PDF Processing tools!



    [8]ページ先頭

    ©2009-2025 Movatter.jp