Use Python Turtle Module to Make Mini Games (3)-Snake

Snake is a classic game on Nokia phones. We can use the Turle module to implement our own snake game.

The effect diagram is as follows
Use Python Turtle Module to Make Mini Games (3)-Snake

In the Snake Snake program, in short, there are several problems that need to be solved:

  1. Initialize a snake out
  2. Snake can move
  3. We can control the snake to run up and down
  4. Generate random food
  5. Snakes can eat food
  6. Snakes can grow tall
  7. Snake hits a wall or hits itself and will die
  8. Display relevant scores and information

The above problems are solved one by one, and the final procedure is also done.
solution:

  1. The principle of initializing the snake is actually similar to the previous turtle race. We instantiate 3 squares at once, adjust the coordinates and put them together.
  2. How does the snake move? After initialization, it is three squares put together. We can put these squares in a list. The first one is naturally the head of the snake, and the last one is the tail of the snake. Each time it moves, it loops forward from the tail of the snake. The squares are moved to the coordinates of the previous square. If there are no coordinates in front of the snake head, it will run forward by default. The effect is that a snake rushes forward.
  3. This is solved through the keyboard monitoring event of the screen. Every time the function is triggered, the angle of the snake head is adjusted inside.
  4. Random food can directly inherit our Turtle class. After initializing the color and size, you can randomly specify the coordinate generation
  5. Judge the distance between the snake head and the food, because our food and the snake head itself are set in size, so we can use the distance function to judge, if it is less than a certain coordinate length, even if it is in contact
  6. The operation of snake length and snake initialization is basically similar. Create a new instance, adjust the coordinates to snake tail, and add it to the list.
  7. By judging the coordinates of the snake’s head and seeing if it has reached the boundary coordinates, or is close to his own body coordinates, we can know if it has collided
  8. The display content can be achieved through the turtle.write function, we only need to adjust the font and coordinates.

In addition to the above issues, there is another point to note that you need to turn off the default animation effect, otherwise every square of your body will be displayed in slow motion, which looks like a weird caterpillar moving. The solution is to turn off the animation effect, and then every time after all the squares have moved, we refresh the interface manually, so that the continuous effect looks like a whole snake moving.

Having said that, let's finally look at the source code.

Just 4 py files, the main file calls the other three types of files

Use Python Turtle Module to Make Mini Games (3)-Snake

main.py

from turtle import Screen
import time
from snake import Snake
from food import Food
from scoreboard import Scoreboard

#初始化画布,设置长度,宽度和标题
screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.title("Snake Game")

#tracer设置为0的作用是关闭动画效果,我们通过timer设置延时,然后通过update手动刷新界面,否则默认的动画效果看起来就是每个方块的移动效果
#想象一下GIF或者CRT显示器的原理,多个画面连续刷新,看起来就像动起来一样
screen.tracer(0)

#实例化三个对象
snake_segments = Snake()
food = Food()
scoreboard = Scoreboard()

#监听上下左右的键盘操作
screen.listen()
screen.onkey(snake_segments.up, "Up")
screen.onkey(snake_segments.down, "Down")
screen.onkey(snake_segments.left, "Left")
screen.onkey(snake_segments.right, "Right")

#布尔值判断是否结束游戏
game_is_on = True
while game_is_on:

#每次停顿0.1秒后刷新一下界面,然后蛇移动一下
    screen.update()
    time.sleep(0.1)
    snake_segments.move()

# 如果蛇头碰见食物了,那么食物刷新随机生成一下,分数加一,蛇身长度加一
    if snake_segments.head.distance(food) < 15:
        print("yum yum yum")
        food.refresh()
        scoreboard.addscore()
        snake_segments.add_segment()

# 如果蛇头撞墙了,那么Game over

    if snake_segments.head.xcor() > 280 or snake_segments.head.xcor() < -280 or snake_segments.head.ycor() > 280 or snake_segments.head.ycor() < -280:
        game_is_on = False
        scoreboard.gameover()

# 如果蛇头撞到身子了,那么Game over,注意列表是从第二节开始的,排除蛇头

    for seg in snake_segments.segments[1:]:

        if snake_segments.head.distance(seg) < 10:
            game_is_on = False
            scoreboard.gameover()

screen.exitonclick()

scoreboard.py

from turtle import Turtle
ALIGNMENT="center"
FONT=("Arial",20,"normal")

#显示分数和Game over等标记

class Scoreboard(Turtle):
    def __init__(self):
        super().__init__()
        self.color('white')
        self.penup()
        self.hideturtle()
        self.score=0
        self.updatescore()

    def updatescore(self):
        self.goto(0, 270)
        self.write(f"SCORE = {self.score}",True, align=ALIGNMENT,font=FONT)
        self.goto(0,250)
#        self.write("-"*300,True, align=ALIGNMENT,font=FONT)

    def addscore(self):
        self.score+=1
        self.clear()
        self.updatescore()

    def gameover(self):
        #self.clear()
        self.goto(0,0)
        self.write(f"GAME OVER",True, align=ALIGNMENT, font=FONT)

snake.py


from turtle import Turtle

MOVE_DISTANCE=20
class Snake:

    #初始化的时候,蛇有三节,一字排开,放到一个列表里
    def __init__(self):
        self.segments = []
        for i in range(3):
            seg = Turtle(shape="square")
            seg.color('white')
            seg.penup()
            seg.goto(0 - 20 * i, 0)
            self.segments.append(seg)
        self.head=self.segments[0]

    #这个是最核心的部分,每次移动的时候,从蛇尾巴往前循环,每个方块往上一个方块的坐标移动,蛇头自动往前跑

    def move(self):
        for seg_num in range(len(self.segments) - 1, 0, -1):
            new_x = self.segments[seg_num - 1].xcor()
            new_y = self.segments[seg_num - 1].ycor()
            self.segments[seg_num].goto(new_x, new_y)
        self.segments[0].forward(MOVE_DISTANCE)

    #蛇头往上跑

    def up(self):
        if self.head.heading() !=270:
            self.head.setheading(to_angle=90)
    #蛇头往下跑

    def down(self):

        if self.head.heading() != 90:
            self.head.setheading(to_angle=270)
    #蛇头往左跑

    def left(self):
        if self.head.heading() !=0:
            self.head.setheading(to_angle=180)
    #蛇头往右跑

    def right(self):
        if self.head.heading() !=180:
            self.head.setheading(to_angle=0)

    #蛇的身子加1,原理是新创建一个实例,然后放到蛇尾巴的位置

    def add_segment(self):
        seg = Turtle(shape="square")
        seg.color('white')
        seg.penup()
        tail = self.segments[-1]
        seg.goto(tail.xcor(),tail.ycor())
        self.segments.append(seg)

food.py

from turtle import  Turtle
import random

class Food(Turtle):
    def __init__(self):
        super().__init__()
        self.shape('circle')
        self.penup()
        #self.shapesize(stretch_len=0.5,stretch_wid=0.5)
        self.color('blue')
        self.speed('fastest')
        # self.goto(random.randint(-280,280),random.randint(-280,280))
        self.refresh()

    def refresh(self):
        self.goto(random.randint(-280, 280), random.randint(-280, 260))

Very simple

Guess you like

Origin blog.51cto.com/beanxyz/2551882