SoFunction
Updated on 2024-12-19

Python+Turtle to make a turtle maze game

(journalism) lede

Hello! Hello everyone! I'm Kimiko.

Throughout the previous posts - I've noticed a characteristic that a lot of peeps like to learn Turtle or game code, right~?

Then today's article is for these 2 aspects of the small friends carefully prepared drops! Turtle + games together to arrange a wave of la!

Turtle from the beginning of the introduction to the basics to practice the case of this article are written to le! Do not think it is a single project oh, want to learn Turtle must learn chapter, do not miss it!

Finally today I will take you to write about one of the three major mazes that utilize Turtle's a turtle breakout oh! The amount of work is still quite large! Are drawn down if the amount of code is more sprinkled, 400 lines of code to complete this "turtles break through the maze of walking" small game!

I. Introduction

1.What is Turtle

Turtle translates to turtle, but we are not talking about this animal, but about a drawing program named after it.

The python documentation describes Turtle itself as a simple, easy-to-use drawing program, perfect for newcomers to the world of programming.

Turtle Drawing Turtle is a built-in module for Python, in short a very simple and fun library.

The main actions are: lifting the brush, after which the action is simply to move the brush without leaving a mark on the canvas; and dropping the brush, which leaves a mark on the canvas as soon as the brush is moved.

Brush action only absolute movement, relative movement, forward (backward) movement, steering (absolute angle, relative angle), circle or arc, point (solid circle), so you can not draw the ellipse, drawing function curves difficult!

2.How to play Turtle

Of course here you need to enter the python programming environment, and then in this python file you can start to get your hands dirty writing code about turtle.

Turtle is a built-in module that comes with the python installation, and it is very easy to call this module by loading it directly using import:

import turtle maybe from turtle import *

This is also the first line of code in the program to get ready to use turtle as a module.

3. Canvas settings

1.1 Setting the canvas size

()       # Return to default size (400, 300)

1.2 Display the window at the default drawing window size, with the window in the center of the screen.

(width, hight[, bg])

Where: width - indicates the width of the canvas (in pixels); Hight - indicates the height of the canvas (in pixels); bg - the background color of the canvas, this parameter can be default, white background by default

1.3 Cases

As:

(800, 600, "green"),indicates that the canvas size is800×600,green canvas。
(width, hight[, x, y])

Where: width, height - represents the width and height of the canvas. When an integer means pixels; as a decimal means the percentage of the computer screen occupied

4. Set background/canvas color

()

II. Turtle's brush settings

(size)

Where: size - the thickness of the brush, expressed in pixels.

Basic methods of drawing

After importing the turtle library drawing module, you can realize the drawing, the basic operation is to draw a straight line forward (backward), rotate (left to right to change direction), draw a circle (arc) and so on.

Here are a few of the most commonly used commands.

1.1 Setting Brush Properties

command show
(width) Used to set the width (i.e. thickness) of the brush, the larger the width the thicker it is.
(color) Used to set the color of the brush, the color parameter can be a string such as "green", "red", or an RGB triad.
(shape) Used to set the shape of the brush, the shape parameter is a string, which mainly contains "turtle", "square" and so on.
(speed) The speed parameter can be a string such as "fast", "slow", etc. or an integer between 0 and 10.

1.2 Commands for Brush Drawing

command instructions
(dis) Move forward dist pixels in the current direction of the brush by a length of
(dist) Move dist pixel lengths in the opposite direction of the current brush
(degree) Turn right three degrees in the direction of the current brush.
(degree) Turn left three degrees in the direction of the current brush.
() Put the brush down and start drawing
() Lift the pen to move without drawing a graph
() Drawing a circle with a positive (negative) radius indicates that the center of the circle is on the left (right) side of the brush Drawing a circle
setx( ) Moves the current x-axis to the specified position
sety( ) Move the current y-axis to the specified position
setheading(degree) Used to set the direction of the brush, the parameter degree is the angle between the direction of the brush and the x-axis of the turtle coordinate system.
ht() Used to hide the brush from view.

III. Final Case Turtle Trivia Game

1. Design Ideas Game Rules

This turtle maze game is designed with three levels, after running the code, there will be a pop-up window to set the corresponding level, you can play that level directly after you want to finish that level, or you can follow the order to break through the level.

Special attention:

A lot of people worry about not being able to pass the level? It's okay, I gave you a hang, this hang is to hold down F1 appeared on the road map of the maze Oh! Hold down F2 is the emergence of a turtle to the starting point of their own route!

2. Preparation session

I used Python3, Pycharm2021, and Turtle modules to import it.

Then the corresponding image material:

3. Formalize the code

# -*- coding: UTF-8 -*-
"""
Source code base: #806965976##
csdn account: Gu Muzi Acres
Turtle maze breakout game
"""
 
import turtle  # Importing the Turtle Mapping Module
import random  # Import random number module
 
game_title = 'Little Turtle Big Maze Breakout Game'  # Name of the game
 
level = 0  # Levels
 
'''Global variables for mapping'''
txt_path = 'map/'  # Map information text file path and name
road_color = (191, 217, 225)  # The color of the labyrinth passage
R, C = 0, 0  # Total number of rows R, total number of columns C of the maze map
cell_size = 20  # The size of a grid
area_sign = {}  # Record entry and exit index locations
mazeList = []  # Map List
 
'''Turtle Object'''
map_t = ()  # Turtle mapping
map_t.speed(0)  # Setting the fastest plotting speeds (mapping)
sign_t = ()  # Drawing entrance and exit markers for turtles
 
auto_t = ()  # Turtles that automatically walk the maze
auto_t.pensize(5)  # Brush thickness (automatic)
auto_t.speed(0)  # Setting the fastest plotting speed (manual)
auto_t.ht()  # Hide the turtle cursor
 
manual_t = ()  # Manually walking a maze of turtles
manual_t.pensize(5)  # Brush thickness (manual)
manual_t.speed(0)  # Setting the fastest plotting speed (manual)
manual_t.shape('turtle')  # Set turtle cursor to small turtle (manual)
manual_t.ht()  # Hide the turtle cursor used to manually walk the maze (manually)
 
# To explore the rules of change in the 4 directions corresponding to indexing
direction = [
    (1, 0),  # Right
    (-1, 0),  # Left
    (0, 1),  # Up
    (0, -1)  # Down
]
 
 
def imoveto(ci, ri):
    """
    Function: move turtles based on index position (without drawing lines)
    :param ci: column index
    :param ri: row index
    :return.
    """
    auto_t.penup()  # Lift the pen
    cx, cy = itoc((ci, ri))  # Convert index positions to coordinate positions
    auto_t.goto(cx, cy)  # Move to the specified position
    auto_t.pendown()  # Putting pen to paper
    auto_t.shape('turtle')  # Set the shape of the turtle cursor
    auto_t.color('red')  # Set the brush color to red
    auto_t.st()  # Show the turtle cursor
 
 
def c_move_to(t, ctuple):  # Move to the specified position
    """
    Function: move to a specified position according to the coordinate position (without drawing a line)
    :param t: turtle object
    :param ctuple: tuple to record the coordinate position
    :return.
    """
    ()  # Hide the turtle cursor
    ()  # Lift the pen
    (ctuple[0], ctuple[1])  # Move to the position specified by the coordinates
    ()  # Putting pen to paper
 
 
def itoc(ituple):
    """
    Convert index positions to actual coordinate positions
    :param ituple: tuple of row and column indices
    :return: actual coordinate position
    """
    ci = ituple[0]
    ri = ituple[1]
    tx = ci * cell_size - C * cell_size / 2  # Calculate the starting point (x-coordinate) of each square based on the index value
    ty = R * cell_size / 2 - ri * cell_size  # Calculate the starting point (y-coordinate) of each square based on the index value
    cx = tx + cell_size / 2  # The x-coordinate of the center of the square
    cy = ty - cell_size / 2  # The y-coordinate of the center of the square
    return (cx, cy)
 
 
def ctoi(cx, cy):
    """
    groundcxcap (a poem)cyFind the corresponding index in the list
    :param cx: xaxis coordinate
    :param cy: yaxis coordinate
    :return: tuple,(ci,ri)
    """
    ci = ((C - 1) * cell_size / 2 + cx) / cell_size  # Calculate column index
    ri = ((R - 1) * cell_size / 2 - cy) / cell_size  # Calculate the row index
    return (int(ri), int(ci))  # Return tuple of row and column indexes
 
 
def get_map(filename):
    """
    Function: Reads the contents of a text file that holds a map into a list
    :param filename: map filename
    :return: list of maps
    """
    with open(filename, 'r') as f:  # Open the file
        fl = ()  # Read all lines
    maze_list = []  # List of saved maps
    for line in fl:  # Split the readings into a two-dimensional list with spaces
        line = ()  # Remove spaces
        line_list = (" ")  # Split into lists with spaces
        maze_list.append(line_list)  # Add the split list to the map list
    return maze_list  # Back to map list
 
 
def draw_square(ci, ri, colorsign):
    """
    Function: draws the small squares that make up the map
    :param ci: column index
    :param ri: row index
    :param colorsign: Fill color
    :return.
    """
    tx = ci * cell_size - C * cell_size / 2  # Calculate the starting point (x-coordinate) of each square based on the index value
    ty = R * cell_size / 2 - ri * cell_size  # Calculate the starting point (y-coordinate) of each square based on the index value
    map_t.penup()  # Lift the pen
    map_t.goto(tx, ty)  # Move to the start of the drawing (top left corner of the square)
    if colorsign == '1':  # Determine if it is a wall (if it is a wall, generate random fill color)
        r = (100, 130)  # Red value
        g = (150, 180)  # Green value
        map_t.color(r, g, 200)  # Specify the color as a randomly generated color
    else:
        map_t.color(colorsign)  # Set to the specified channel color
    map_t.pendown()  # Putting pen to paper
    map_t.begin_fill()  # Filling starts
    for i in range(4):  # Drawing squares
        map_t.fd(cell_size)
        map_t.right(90)
    map_t.end_fill()  # End of filling
    map_t.ht()  # Hide the turtle cursor
 
 
def draw_map(mazelist):
    """
    Function: Iterate through a list of maps to draw a maze map
    :param mazelist: list where map data is kept
    :return.
    """
    (0)  # Hide animation effects
    global area_sign  # Global variable recording the location of the entry and exit indexes
    for ri in range(R):  # Traversing rows
        for ci in range(C):  # Traversing columns
            item = mazelist[ri][ci]
            if item in ['1']:  # Judgment wall
                draw_square(ci, ri, '1')  # Drawing walls
            elif item == "S":  # Judgment entry
                draw_square(ci, ri, road_color)  # Drawing channels
                draw_sign(ci - 1, ri, 'Entrance')  # Marking the entrance
                area_sign['entry_i'] = (ci, ri)  # Preserve the index of entries
            elif item == "E":  # Judging the exit
                draw_square(ci, ri, road_color)  # Drawing channels
                draw_sign(ci - 1, ri, 'Exit')  # Mark the exit
                area_sign['exit_i'] = (ci, ri)  # Save export indexes
            else:
                draw_square(ci, ri, road_color)  # Drawing channels
    (1)  # Display animated effects
 
 
def draw_sign(ci, ri, word):
    """
    Function: draw entry and exit markers
    :param ci: column index
    :param ri: row index
    :param word: Marker text content
    :return.
    """
    cx, cy = itoc((ci, ri))  # Convert index positions to coordinate positions
    sign_t.ht()  # Hide the turtle cursor
    sign_t.penup()  # Lift the pen
    sign_t.goto(cx, cy)  # Move to the marker position
    sign_t.color('red')  # Set the brush to red
    sign_t.write(word, font=('Bold', 12, 'normal'))  # Drawing markup text
 
 
def win_tip():
    """
    Function: Make a pass hint
    :return.
    """
    global level
    c_move_to(manual_t, (-150, 0))
    manual_t.color('blue')
    if int(level) == 3:
        manual_t.write(''\nCongratulations on your successful clearance!'', font=('Bold', 20, 'bold'))
        (, key='Return')  # Listening for the Enter key to be pressed to exit the game
    else:
        manual_t.write('\nCongratulations on passing the level! \nPress Enter to go to the next level!', font=('Bold', 20, 'bold'))
        level += 1
        manual_t.color('red')
        (level_init, key='Return')  # Listen for the Enter key to be pressed
 
 
def manual_move(d):
    """
    Function: generic explore-and-move function when walking the maze manually
    :param d: Rule for changing indexes when walking in different directions.
    :return.
    """
    dc, dr = d  # Assign the tuple representing the direction to two variables dc and dr, where dc is the direction of the x-axis and dr is the direction of the y-axis, respectively
    rici = ctoi(round(manual_t.xcor(), 1) + dc * cell_size, round(manual_t.ycor(), 1) + dr * cell_size)  # Get row and column indexes
    point = mazeList[rici[0]][rici[1]]  # Get the value of the corresponding point in the map list
    print('Move:', rici, point)
    if point == '0':  # Access
        manual_t.color('red')
        mazeList[rici[0]][rici[1]] = '$'  # Mark the current location as explored
        manual_t.forward(cell_size)  # Move forward
        print('00')
    elif point == '$':  # Explored
        manual_t.color(road_color)  # Draw lines of the same color as the channel to achieve the effect of erasing traces
        mazeList[rici[0] + dr][rici[1] - dc] = '0'  # Set the previous point at the current position as unexplored (intended to be unmarked)
        manual_t.forward(road_color)  # Move forward
        manual_t.color('red')
    elif point == 'E':  # Exports
        win_tip()
 
 
def up_move():  # Toward the top
    manual_t.setheading(90)  # Setting up turtle orientation
    manual_move(direction[2])  # Manually explore and move
 
 
def down_move():  # Face down
    manual_t.setheading(270)  # Setting up turtle orientation
    manual_move(direction[3])  # Manually explore and move
 
 
def left_move():  # To the left
    manual_t.setheading(180)  # Setting up turtle orientation
    manual_move(direction[1])  # Manually explore and move
 
 
def right_move():  # To the right
    manual_t.setheading(0)  # Setting up turtle orientation
    manual_move(direction[0])  # Manually explore and move
 
 
def manual_path():
    """
    Function: manual maze walking
    :return.
    """
    manual_t.clear()  # Clear the drawing
    auto_t.ht()  # Hide the turtles
    auto_t.clear()  # Clear the drawing
    global mazeList  # Define global variables
    mazeList = get_map(txt_path)  # Re-read map data
    # print(area_sign['entry_i'][0],area_sign['entry_i'][1])
    c_move_to(manual_t, itoc(area_sign['entry_i']))  # Move to the entrance position
    manual_t.st()  # Show the turtle cursor used to manually walk the maze
    manual_t.width(3)  # Set the brush thickness to 3 pixels
    manual_t.color('red')  # Set the brush to red
    manual_t.getscreen().listen()  # Getting the TurtleScreen in focus
    manual_t.getscreen().onkeyrelease(up_move, 'Up')  # Press the up arrow key
    manual_t.getscreen().onkeyrelease(down_move, 'Down')  # Press the down arrow key
    manual_t.getscreen().onkeyrelease(left_move, 'Left')  # Press the left arrow key
    manual_t.getscreen().onkeyrelease(right_move, 'Right')  # Press the right arrow key
 
 
def auto_path():
    """
    Function: view answers (automatic maze walking)
    :return.
    """
    global mazeList  # Define global variables
    mazeList = get_map(txt_path)  # Re-read map data
    manual_t.ht()  # Hide the turtles
    manual_t.clear()  # Clear the drawing
    auto_t.clear()  # Clear the drawing
    auto_t.pensize(5)  # Set the brush thickness
    auto_t.speed(0)  # Drawing speed
    auto_t.ht()  # Hide the turtle cursor
    find(mazeList)  # Start exploring
 
 
def find(mazeList):
    """
    Function: Start exploring
    :param mazeList: list of maps
    :return.
    """
    auto_t.clear()  # Clear help
    start_r, start_c = 0, 0
    for ri in range(R):
        for ci in range(C):
            item = mazeList[ri][ci]
            if item == "S":
                start_r, start_c = ri, ci
    auto_t.penup()  # Lift the pen
    draw_path(start_c, start_r)
    find_next(mazeList, start_c, start_r)
 
 
def find_next(mlist, ci, ri):
    """
    Function: Recursive search to determine if a pathway is a pathway or not
    :param mlist: map list
    :param ci: column index
    :param ri: row index
    :return: Boolean value indicating whether it is a pathway or not
    """
    if mlist[ri][ci] == "E":
        imoveto(ci, ri)  # Move to the exit
        return True
    if not (0 <= ci < C and 0 <= ri < R):  # Determine if the location is illegal
        return False
    if mlist[ri][ci] in ['1', '$']:  # Determine if it's a wall or explored
        return False
    mlist[ri][ci] = "$"  # Marked as explored
    for d in direction:  # Try to explore in different directions to see if it's a pathway, and if you find a pathway, you don't go any further
        dc, dr = d  # # Assign the values of the index change rules to dc and dr, where dc is the x-axis direction and dr is the y-axis direction, respectively
        found = find_next(mlist, ci + dc, ri + dr)  # Recursive calls
        if found:  # If it's a pathway then draw the line
            draw_path(ci, ri)  # Mapping the lines
            return True  # Return True and explore no further
    return False  # Returns False when all directions are not passable
 
 
def draw_path(ci, ri, color="green"):  # For automated plotting
    """
    Function: move turtles based on index position (draw lines)
    :param ci: column index
    :param ri: row index
    :param color: brush color
    :return.
    """
    auto_t.st()  # Show the turtle cursor
    cx, cy = itoc((ci, ri))  # Convert index positions to coordinate positions
    auto_t.color(color)
    auto_t.goto(cx, cy)
 
 
def level_init():
    """
    Function: level initialization
        Game Rules:
        Press F2 key to start walking the maze manually; press F1 key to view the answer
        Press ↑↓←→ arrow keys to control the movement of the turtle, after the success, press Enter to enter the next level!
    :return.
    """
    manual_t.clear()  # Clear the drawing
    auto_t.clear()  # Clear the drawing
    ()  # Clear the drawing
    global txt_path, level, mazeList, R, C  # Define global variables
    if level == 1:  # Map files and backgrounds for the first level
        txt_path = "map/"
        levelbg = 'image/'
    elif level == 2:  # Map files and backgrounds for level 2
        txt_path = "map/"
        levelbg = 'image/'
    elif level == 3:  # Map files and backgrounds for level 3
        txt_path = "map/"
        levelbg = 'image/'
    else:
        ()  # Exit the program
        return
    mazeList = get_map(txt_path)  # Getting map data
    R, C = len(mazeList), len(mazeList[0])
    (width=C * cell_size + 50, height=R * cell_size + 100)  # Window resizing based on maps
    (levelbg)  # Setting the background image
 
    '''  
    # If you want to manually plot the number of levels, you can use the following two lines of code
    cmoveto(turtle, (1 * cellsize - C * cellsize / 2, R * cellsize / 2+10))
    ('Levels:'+str(int(level)), font=('Song Style', 16, 'normal'))    
    '''
    ()  # Hide the turtle cursor
    draw_map(mazeList)  # map

IV. Effects

1. Run the code

2. Level I

This is holding down F1 so the roadmap appears!

3. Level II

It's holding down F2 so it's manually breaking in by itself haha!

4. Level III

Above is Python + Turtle to create a turtle maze game in detail, more information about Python Turtle maze game please pay attention to my other related articles!