python小游戏–简版贪吃蛇(turtle实现)

  • Post author:
  • Post category:python


一、游戏规则:

1.游戏开始,通过键盘上下左右控制贪吃蛇移动方向,去找食物,贪吃蛇吃到食物就会增加一节

2.贪吃蛇碰到自身就会提示死亡(简版中没有设置真实死亡)

3.贪吃蛇碰到墙壁后会自动从另一边穿出(常规的是碰墙就死,但是我不想死的那么快,哈哈哈)

二、代码实现

1.工具:python(random,turtle库,没安装的需要安装一下,调出命令行:pip install turtle)

turtle是一个简单的画图的库(也被称为海龟画图),在屏幕中有一个横轴为x,纵轴为y的坐标系,最中间是原点(0,0)位置开始,如下图。

图片

2.画图流程:提笔(penup)–定位(goto)–绘画(forward)落笔(pendown)

3.原理:结合turtle的画图功能,贪吃蛇的蛇身就可以通过画出一个个方块,并涂上颜色来实现,同理食物也是如此。

4.具体实现:

4.1.贪吃蛇我们可以通过坐标列表来存储,设置变量为snake=[[0,0],[0,10],[0,20]]

4.2.食物设置为随机变量,food=[r.randrange(-25,25)*10,r.randrange(-25,25)*10]

4.3.方块绘制:

编写单个方块的绘图函数,需要参数绘制的坐标位置想x,y,绘制的边长size,填充的颜色color,对蛇身和食物分别遍历达到绘制效果

#绘制方块
def square(x,y,size,color):
    t.penup()
    t.goto(x,y)
    t.pendown()
    t.color(color) #设置颜色
    t.begin_fill() #渲染
    for i in range(4):
        t.forward(size)
        t.left(90)
    t.end_fill()#渲染

#画食物
square(food[0],food[1],10,'red')
    
#画蛇
for i in snake:
    square(i[0],i[1],10,'black')

4.4.方向调整:

给定一个目标作为方向aim[0,10],就是说以贪吃蛇的蛇头为原点,y增加10,就是对照上述坐标轴就是向上移动10个单位,同理aim[0,-10],就是向下,aim[10,0],就是向右,aim[-10,0],就是向左

aim=[0,10] #初始化

#动态调整移动的方向
def change_direction(x,y):
    aim[0]=x
    aim[1]=y

#监听键盘实现方向改变
t.listen()
t.onkey(lambda :change_direction(0,10),'Up')
t.onkey(lambda :change_direction(0,-10),'Down')
t.onkey(lambda :change_direction(10,0),'Right')
t.onkey(lambda :change_direction(-10,0),'Left')

4.5.方块的移动:

先深度拷贝一份蛇的头部坐标,用蛇的头部坐标x,y分别加上移动的目标aim的x,y作为新的头部,然后添加到snake列表,并去掉最后一个方块。

def move_snake():
    head=c.deepcopy(snake[-1]) #复制一份头部坐标
    #确定方向
    head=[head[0]+aim[0],head[1]+aim[1]] #确定新头的坐标
    snake.pop(0) #去尾巴
    snake.append(head) #添加头
    #删除之前的动画
    t.clear()
    #画蛇
    for i in snake:
        square(i[0],i[1],10,'black')

4.6.边界的判断

判断贪吃蛇的头部是否超出四周边界,超出则减去整个屏幕的边长,达到穿墙的效果

#判断边界
def inside(head):
    if head[0]>250:
        head[0]-=250*2
    elif head[0]<-250:
        head[0]+=250*2
    if head[1]>250:
        head[1]-=250*2
    elif head[1]<-250:
        head[1]+=250*2
    return head

综合上述所有功能:

1.导入所需要模块,初始化变量

2.功能函数的编写

3..移动过程中做死亡和穿墙判断

4.利用turtle.ontimer()做递归,间隔时间time=300毫秒,达到循环执行的效果

import turtle as t
import copy as c
import random as r

#初始化,模拟蛇,就是一个方块列表
snake=[[0,0],[0,10],[0,20]]
aim=[0,10] #移动目标
food=[r.randrange(-25,25)*10,r.randrange(-25,25)*10]
time=300

#动态调整移动的方向
def change_direction(x,y):
    aim[0]=x
    aim[1]=y
    
#画出方块
def square(x,y,size,color):
    t.penup()
    t.goto(x,y)
    t.pendown()
    t.color(color) #设置颜色
    t.begin_fill() #渲染
    for i in range(4):
        t.forward(size)
        t.left(90)
    t.end_fill()#渲染

#判断边界
def inside(head):
    if head[0]>250:
        head[0]-=250*2
    elif head[0]<-250:
        head[0]+=250*2
    if head[1]>250:
        head[1]-=250*2
    elif head[1]<-250:
        head[1]+=250*2
    return head

#移动--解析:头部添加方块,尾巴消除一个方块
# 最后画的最上面的方块--设定为头部
def move_snake():
    head=c.deepcopy(snake[-1]) #复制一份头部坐标
    #确定方向
    head=[head[0]+aim[0],head[1]+aim[1]] #确定新头的坐标
    if head in snake:
        print('game over')
        square(head[0],head[1],10,'yellow')
        
    #边界判断    
    inside(head)
    #移动蛇
    if head==food:
        food[0]=r.randrange(-24,24)*10
        food[1]=r.randrange(-24,24)*10
    else:
        snake.pop(0) #去尾巴
    snake.append(head) #添加头

    #删除之前的动画
    t.clear()
    
    #画食物
    square(food[0],food[1],10,'red')
    
    #画蛇
    for i in snake:
        square(i[0],i[1],10,'black')
        
    #循环执行
    t.update() #刷新
    t.ontimer(move_snake,time) #递归
    
    
t.tracer(False)#除去动画效果
t.hideturtle() #隐藏箭头
#监听键盘
t.listen()
t.onkey(lambda :change_direction(0,10),'Up')
t.onkey(lambda :change_direction(0,-10),'Down')
t.onkey(lambda :change_direction(10,0),'Right')
t.onkey(lambda :change_direction(-10,0),'Left')
#设定屏幕大小
t.setup(500,500)
#运行
move_snake()
t.done() #暂停屏幕

三、总结

用turtle实现的贪吃蛇功能有限,控制精度也不足,但是非常适合初学者练手,主要是体会下python实现一个项目的过程,和加深对面向对象的理解。



版权声明:本文为sweettwo2原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。