突然想把去年写的小游戏练习整合一下,写一个简单的教学文章吧。

该篇主要讲解利用python中turtle包制作小游戏,不涉及pygame的使用,仅用pycharm就可实现

0.理清游戏思路

  要实现的效果如下图所示:

基于python的贪吃蛇游戏设计 python 贪吃蛇_pygame

黑色是蛇,红色利用随机函数生成的苹果,蛇没吃到一个苹果,就会增一节,同时下一个苹果随机生成在框内。

蛇的运动通过刷新页面来表示,每刷新一次,画图函数会在蛇头位置多画一个小方格,并删除蛇尾位置的小方格。以此来实现蛇的运动。

蛇不可撞到边框,否则游戏失败(停止运行)。

其中,蛇和苹果利用海龟画图(turtle)实现。

1.turtle库

turtle是python自带的一个库,主要用于画图。(据说是像海龟爬图?

turtle库中自带许多画图函数:(这里只列举贪吃蛇所用到的部分函数)

up()

起笔函数

goto(x,y)

去到(x,y)位置的函数

forward(size)

朝特定方向走,参数表示画线的长度

left(size)

转向函数,参数为调转度数(蛇每次调转90度,则填90)

begin_fill()

无参,开始绘图(落笔)

end_fill()

无参,绘图结束

color(color_name)

设置线条颜色,括号内填写颜色名称

因为该"画图"动作需要循环调用,因此可以写一个函数将该功能包裹起来,以方便多次循环使用。

该部分代码:

from turtle import *
from random import randrange

                        #注意导包,(以下需要用到随机函数,所以也要导包随机函数)

def square(x,y,size,color_name):  #函数名称可自定义,参数:需要用的什么就设置什么
    up()
    goto(x,y)                     #画笔移动到某一点
    color(color_name)             #设置画笔颜色
    begin_fill()                  #落笔开画

    forward(size)                 #画笔画直线
    left(90)                      #转向90度        以下代码段表示每次画一个小方格
    forward(size)
    left(90)
    forward(size)
    left(90)
    forward(size)
    left(90)
    end_fill()                    #绘图结束

2.定义小蛇和苹果

蛇的初始长度肯定不能是一个小方格吧

这里我的初始小蛇定义了四个小方格的长度,每个小方格为10;(可自定义,提示:最好为整数,避免蛇头与苹果”对不上“的情况出现。)

snack=[[0,0],[10,0],[20,0],[30,0]]
apple_x=randrange(-20,20)*10          #定义小苹果,和苹果的位置坐标
apple_y=randrange(-20,20)*10
aim_x=0
aim_y=10                              #蛇的起始位置坐标

定义动作函数

def change(x,y):
    global aim_x,aim_y
    aim_x=x
    aim_y=y

3.”撞墙“的判断

先贴一下我的代码段

def inside():
    if -210<=snack[-1][0]<=200 and -210<=snack[-1][1]<210 :
        return True
    else:
        return False

inside函数判断小蛇是否在画布内,即是否撞墙。

这里我把画布的大小设置为420*420(210是均分坐标,从-210到+210)。因为蛇的每一节身子长度为10,所以判断条件为小蛇头部是否小于等于200的大小,小于返回true,可以继续运行,否则false,结束运行。

4.函数循环使用

相当于是把上述函数嵌套在一个新的Loop函数内了,以方便于每刷新一次就调用一次Loop。

clear()和update()连用——刷新:擦除旧的线,画上新的线。

def gameLoop ():                         #自定义循环函数
    global apple_x,apple_y               #需要用到外面的全局变量
    clear()                              #擦除旧图的函数,清理函数
    snack.append([snack[-1][0]+aim_x,snack[-1][1]+aim_y])    #小蛇的出现位置
    if not inside():                                         #判断是否还在画布内
        return
    if snack[-1][0]!=apple_x or snack[-1][1]!=apple_y :
        snack.pop(0)                           #判断小蛇安全前行,擦除尾部,使用pop函数删除
    else:
        apple_x=randrange(-20,20)*10           #吃到苹果,则随机生成另一个新的苹果
        apple_y=randrange(-20,20)*10
    for n in range(len(snack)):
        square(snack[n][0],snack[n][1],10,"black")    #调用画图函数,定义黑色小蛇,红色苹果
    square(apple_x,apple_y,10,"red")
    ontimer(gameLoop,200)                            #调用循环函数,每隔一段时间调用一次
    update()                                         #更新

5.收尾:设置画布、隐藏海龟画图小箭头、监听函数的使用、以及键盘操控

注意:setup(420,420,0,0)意为设置一个420*420大小的平面画布,先前210是正向坐标!! 

setup(420,420,0,0)        #设置画布
hideturtle()              #隐藏海龟画图的小标签,为了美观
tracer(False)             #不显示轨迹路线
listen()                  #监听函数
onkey(lambda :change(0,10),"w")      #键盘操控,点击相应案件实现改变方向操作
onkey(lambda :change(0,-10),"s")
onkey(lambda :change(10,0),"d")
onkey(lambda :change(-10,0),"a")
gameLoop()                            #循环函数
done()

———————————————————————————————————————————

来一个代码整合:

from turtle import *
from random import randrange

def square(x,y,size,color_name):
    up()
    goto(x,y)
    color(color_name)
    begin_fill()

    forward(size)
    left(90)
    forward(size)
    left(90)
    forward(size)
    left(90)
    forward(size)
    left(90)
    end_fill()

snack=[[0,0],[10,0],[20,0],[30,0]]
apple_x=randrange(-20,20)*10
apple_y=randrange(-20,20)*10
aim_x=0
aim_y=10
def change(x,y):
    global aim_x,aim_y
    aim_x=x
    aim_y=y
def inside():
    if -210<=snack[-1][0]<=200 and -210<=snack[-1][1]<210 :
        return True
    else:
        return False
def gameLoop ():
    global apple_x,apple_y
    clear()
    snack.append([snack[-1][0]+aim_x,snack[-1][1]+aim_y])
    if not inside():
        return
    if snack[-1][0]!=apple_x or snack[-1][1]!=apple_y :
        snack.pop(0)
    else:
        apple_x=randrange(-20,20)*10
        apple_y=randrange(-20,20)*10
    for n in range(len(snack)):
        square(snack[n][0],snack[n][1],10,"black")
    square(apple_x,apple_y,10,"red")
    ontimer(gameLoop,200)
    update()

setup(420,420,0,0)
hideturtle()
tracer(False)
listen()
onkey(lambda :change(0,10),"w")
onkey(lambda :change(0,-10),"s")
onkey(lambda :change(10,0),"d")
onkey(lambda :change(-10,0),"a")
gameLoop()
done()