Python Turtle 모듈을 사용하여 미니 게임 만들기 (3) -Snake

Snake는 Nokia 휴대 전화의 고전 게임입니다. Turle 모듈을 사용하여 자체적 인 뱀 게임을 구현할 수 있습니다.

효과 다이어그램은 다음과 같습니다
Python Turtle 모듈을 사용하여 미니 게임 만들기 (3) -Snake

Snake Snake 프로그램에는 간단히 말해서 해결해야 할 몇 가지 문제가 있습니다.

  1. 스네이크 아웃 초기화
  2. 뱀은 움직일 수 있습니다.
  3. 뱀이 위아래로 뛰도록 제어 할 수 있습니다.
  4. 무작위 음식 생성
  5. 뱀은 음식을 먹을 수 있습니다
  6. 뱀은 키가 커질 수 있습니다.
  7. 뱀이 벽에 부딪 히거나 스스로 부딪쳐 죽습니다.
  8. 관련 점수 및 정보 표시

위의 문제는 하나씩 해결되고 최종 절차도 완료됩니다.
해결책:

  1. 뱀을 초기화하는 원리는 실제로 이전 거북이 종족과 비슷합니다. 3 개의 사각형을 한 번에 인스턴스화하고 좌표를 조정하여 합칩니다.
  2. 뱀은 어떻게 움직입니까? 초기화 후에는 세 개의 사각형이 합쳐집니다.이 사각형을 목록에 넣을 수 있습니다. 첫 번째 사각형은 당연히 뱀의 머리이고 마지막 하나는 뱀의 꼬리입니다. 움직일 때마다 뱀의 꼬리에서 앞으로 순환합니다. 정사각형은 이전 정사각형의 좌표로 이동하며, 뱀 머리 앞에 좌표가 없으면 기본적으로 앞으로 실행되며 뱀이 앞으로 돌진하는 효과가 있습니다.
  3. 이는 화면의 키보드 이벤트를 모니터링하여 해결되며, 기능이 트리거 될 때마다 내부의 뱀 머리 각도를 조절하여 해결됩니다.
  4. 임의의 음식은 Turtle 클래스를 직접 상속받을 수 있으며 색상과 크기를 초기화 한 후 좌표 생성을 임의로 지정할 수 있습니다.
  5. 우리의 음식과 뱀 머리 자체의 크기가 설정되어 있기 때문에 뱀 머리와 음식 사이의 거리를 판단합니다. 그래서 거리 기능을 사용하여 접촉되어 있어도 특정 좌표 길이 미만인지 판단 할 수 있습니다.
  6. 스네이크 길이와 스네이크 초기화 동작은 기본적으로 비슷하며, 새 인스턴스를 생성하고 스네이크 테일 좌표를 조정 한 후 목록에 추가합니다.
  7. 뱀의 머리 좌표를 판단하고 경계 좌표에 도달했는지 또는 자신의 신체 좌표에 가까워 졌는지 확인하면 충돌 여부를 알 수 있습니다.
  8. 표시 내용은 turtle.write 함수로 얻을 수 있으며 글꼴과 좌표 만 조정하면됩니다.

위의 문제 외에도 기본 애니메이션 효과를 꺼야한다는 또 다른 점이 있습니다. 그렇지 않으면 신체의 모든 사각형이 이상한 애벌레가 움직이는 것처럼 보이는 슬로우 모션으로 표시됩니다. 해결책은 애니메이션 효과를 끄고 모든 사각형이 움직일 때마다 인터페이스를 수동으로 새로 고쳐 연속 효과가 전체 뱀이 움직이는 것처럼 보이도록하는 것입니다.

그러고 나서 마침내 소스 코드를 살펴 보겠습니다.

단지 4 개의 py 파일, 주 파일은 다른 세 가지 유형의 파일을 호출합니다.

Python Turtle 모듈을 사용하여 미니 게임 만들기 (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))

아주 간단

추천

출처blog.51cto.com/beanxyz/2551882