Python实现贪吃蛇
🚲turtle模块 Python的turtle模块是一个非常基础的绘图库,它允许用户创建一个画布并在上面绘制图形。这个模块通常用于教学目的,特别是适合初学者学习编程和理解基本的图形概念。 turtle的一些关键特性:
turtle模块非常适合用来创建游戏、绘制复杂的几何图形,或者作为教授编程逻辑和控制结构的工具。
import turtle
import copy
from random import randrange
创建画布和设置标题
wn = turtle.Screen()
wn.title('贪吃蛇游戏')
保持打开绘图窗口
# 不让屏幕立马消失
turtle.done()
turtle.done()是一个非常重要的函数,它用于结束绘图操作并保持打开绘图窗口,直到用户关闭该窗口。这允许用户观察绘制的图形,而不会因为程序的结束而丢失绘图结果。 使用场景 在绘制图形或动画的最后,你会调用turtle.done()来结束你的绘图脚本。例如,在绘制完一个图形或完成一个动画循环后,你可以使用它来防止程序立即退出,从而让用户有足够的时间来查看结果。
注意事项
设置蛇的长度
snake = [[0, 0], [0, 10], [0, 20]]
这里初始化了蛇的三个部分,每个部分由一个列表表示,列表包含两个元素,分别代表蛇的x和y坐标。在这个例子中,蛇有三个部分,初始位置分别是(0, 0)、(0, 10)和(0, 20)。
蛇移动的方向
aim = [0, 10]
aim列表定义了蛇的移动方向,其中第一个元素是水平方向(向右为正,向左为负),第二个元素是垂直方向(向下为正,向上为负)。这里,蛇默认向上移动。
设置食物
food = [-10, 0]
food列表定义了食物的初始位置,同样使用x和y坐标表示。这里食物的初始位置是(-10, 0)。
这些初始化步骤为游戏设置了基本的起点,包括蛇的初始位置和方向、食物的位置以及游戏窗口的标题。
# 改变蛇移动的方向
def change_direction(x, y):
aim[0] = x
aim[1] = y
参数作用
注意事项
def square(x, y, size, color):
# 抬起画笔
turtle.penup()
# 画笔痕迹
turtle.goto(x, y)
# 放下画笔
turtle.pendown()
# 进行渲染
turtle.color(color)
turtle.begin_fill()
# 在画布上画四笔转一圈生成一个方块
for i in range(4):
turtle.forward(size)
turtle.left(90)
turtle.end_fill()
turtle.penup() 这是让画笔抬起,这样当乌龟移动到绘制方块的起始位置时,不会在画布上留下痕迹。turtle.goto(x, y) 这是让乌龟移动到坐标 (x, y) 的位置,即方块左上角的起始位置。 turtle.pendown() 放下画笔,这样接下来的移动就会在画布上绘制线条。 turtle.color(color) 设置接下来绘制的图形的颜色。 turtle.begin_fill() 这行代码指示 turtle 开始填充封闭图形的内部。 turtle.end_fill() 结束填充过程,封闭图形的最后面,完成方块的绘制。
for i in range(4):
turtle.forward(size)
turtle.left(90)
循环执行四次,每次绘制方块的一边。turtle.forward(size) 让乌龟前进 size 个单位,turtle.left(90) 让乌龟左转90度,从而改变方向绘制下一条边。
这个函数可以被用来在 turtle 画布上绘制贪吃蛇游戏中的蛇的身体部分和食物。通过改变 size 和 color 参数,可以创建不同大小和颜色的方块。
def inside(head):
return -250 < head[0] < 250 and -250 < head[1] < 250
函数体内的 return 语句包含了一个布尔表达式,用于检查 head 中的 x 和 y 坐标是否同时满足以下条件:
如果两个条件都为真,函数返回 True,表示蛇头在游戏窗口内;如果任一条件不满足(即蛇头坐标超出了这个范围),函数返回 False,表示蛇头已经撞到了游戏边界。
注意事项 在实际的游戏实现中,你需要根据实际的游戏窗口大小来调整函数中的边界值。上面的代码中使用的边界值 -250 和 250 是示例,具体值应根据你的游戏设计来设定。
# 定义蛇的移动的函数
def sanke_move():
head = copy.deepcopy(snake[-1])
head = [head[0] + aim[0], head[1] + aim[1]]
print(head[0], head[1])
# 判断是否发生了碰撞
if head in snake or not inside(head):
print("Game Over!")
square(head[0], head[1], 10, "red")
return
# 判断蛇碰到食物后的操作
if head == food:
food[0] = randrange(-15, 15) * 10
food[1] = randrange(-15, 15) * 10
else:
snake.pop(0)
snake.append(head)
turtle.clear()
square(food[0], food[1], 10, "blue")
# 遍历蛇的列表画出蛇的长度
for body in snake:
square(body[0], body[1], 10, "black")
# 更新,使动画的出现不是那么突兀
turtle.update()
turtle.ontimer(sanke_move, 300)
sanke_move 函数是贪吃蛇游戏中控制蛇移动的核心函数。
sanke_move函数负责根据用户的操作更新蛇的位置,检查游戏状态(如是否吃到食物或游戏是否结束),并更新屏幕上的显示,是贪吃蛇游戏的控制中心。
设置屏幕大小
turtle.setup(500, 500)
这行代码设置了turtle画布的宽度和高度为500像素。这意味着蛇将在一个500x500像素的窗口内移动。
去除绘制动画
turtle.tracer(False)
turtle.tracer()函数控制是否在绘制图形时显示动画。将其设置为False可以关闭绘制方块时的动画效果,使方块几乎是立即出现的,这对于需要快速更新屏幕的游戏来说是必要的。
隐藏画笔(乌龟)
turtle.hideturtle()
这行代码隐藏了turtle模块中用于绘制的“乌龟”(即画笔)。在大多数游戏中,我们不需要看到这个画笔,只需要看到它绘制的图形。
监听键盘事件
turtle.listen()
turtle.listen()开始监听键盘事件,使得我们可以为特定的按键绑定特定的函数。
绑定键盘按键
turtle.onkey(lambda: change_direction(0, 10), "Up")
turtle.onkey(lambda: change_direction(0, -10), "Down")
turtle.onkey(lambda: change_direction(-10, 0), "Left")
turtle.onkey(lambda: change_direction(10, 0), "Right")
这四行代码将键盘的上下左右箭头键与change_direction函数绑定。当用户按下相应的箭头键时,会调用change_direction函数,并传入相应的参数,这些参数定义了蛇的新移动方向。
lambda函数是一个匿名函数,它创建了一个新的函数对象,这里用于简化onkey的回调函数。
import turtle
import copy
from random import randrange
# 设置蛇的长度
snake = [[0, 0], [0, 10], [0, 20]]
# 蛇移动的方向(默认向上移动)
aim = [0, 10]
# 设置食物
food = [-10, 0]
wn = turtle.Screen()
# 设置标题
wn.title('贪吃蛇游戏')
# 改变蛇移动的方向
def change_direction(x, y):
aim[0] = x
aim[1] = y
def square(x, y, size, color):
# 抬起画笔
turtle.penup()
# 画笔痕迹
turtle.goto(x, y)
# 放下画笔
turtle.pendown()
# 进行渲染
turtle.color(color)
turtle.begin_fill()
# 在画布上画四笔转一圈生成一个方块
for i in range(4):
turtle.forward(size)
turtle.left(90)
turtle.end_fill()
def inside(head):
return -250 < head[0] < 250 and -250 < head[1] < 250
# 定义蛇的移动的函数
def sanke_move():
head = copy.deepcopy(snake[-1])
head = [head[0] + aim[0], head[1] + aim[1]]
print(head[0], head[1])
# 判断是否发生了碰撞
if head in snake or not inside(head):
print("Game Over!")
square(head[0], head[1], 10, "red")
return
# 判断蛇碰到食物后的操作
if head == food:
food[0] = randrange(-15, 15) * 10
food[1] = randrange(-15, 15) * 10
else:
snake.pop(0)
snake.append(head)
turtle.clear()
square(food[0], food[1], 10, "blue")
# 遍历蛇的列表画出蛇的长度
for body in snake:
square(body[0], body[1], 10, "black")
# 更新,使动画的出现不是那么突兀
turtle.update()
turtle.ontimer(sanke_move, 300)
# 设置屏幕的大小
turtle.setup(500, 500)
# 去除一个一个画方块的动画
turtle.tracer(False)
# 去掉箭头(画画用的画笔)
turtle.hideturtle()
# 用来监听键盘(获取键盘的事件)
turtle.listen()
# 用来监听函数(通过控制转向函数达到让蛇转向的目的)
turtle.onkey(lambda: change_direction(0, 10), "Up")
turtle.onkey(lambda: change_direction(0, -10), "Down")
turtle.onkey(lambda: change_direction(-10, 0), "Left")
turtle.onkey(lambda: change_direction(10, 0), "Right")
sanke_move()
# 不让屏幕立马消失
turtle.done()