Python-Turtle-贪吃蛇

Python-Turtle海龟版-贪吃蛇

py源码同一目录下有个GreedySnake文件夹, 装有相关图像/音频文件
我已经打包成exe文件, 点开即玩
Python海龟版-贪吃蛇-exe文件

玩家一 使用 a / d键移动
玩家二 使用 方向键移动


源码如下:

import turtle
import time
import threading
from random import randint
import simpleaudio as sa
eatMusic = sa.WaveObject.from_wave_file('GreedySnake/1.wav')  # 吃到的音效
bgm = sa.WaveObject.from_wave_file("GreedySnake/bgm.wav") # 背景音乐
border = sa.WaveObject.from_wave_file("GreedySnake/border.wav")  # 撞墙的音效
ate_tail = sa.WaveObject.from_wave_file("GreedySnake/ate_tail.wav")

FORWARD_PX = 45  # 前进的距离 px

t1stampList = []  # 保存海龟的 x坐标, y坐标, stampID
t2stamplist = []  # 保存的元素是: [xpos, ypos, stampId]


######## 食物
foot_turtle = turtle.Turtle()
foot_turtle.up()
foot_turtle.speed(0)
turtle.register_shape("GreedySnake/3.gif")
turtle.register_shape("GreedySnake/8_.gif")  # 随机移动的食物
turtle.register_shape("GreedySnake/7_.gif")  # 随机移动的毒药
foot_turtle.shape("GreedySnake/3.gif")
movefood = None  # 移动的食物
movepoison = None   # 移动的毒药

def rand_food(randmove_turtle, moveRange):
    # randmove_turtle是要随机移动的海龟, moveRange是随机移动的范围 整型, 最小2表示范围在全屏, 值越大范围越小
    HEIGHT = turtle.window_height()
    WIDTH = turtle.window_width()
    randmove_turtle.setpos((randint(-WIDTH//moveRange, WIDTH//moveRange), randint(-HEIGHT//moveRange, HEIGHT//moveRange)))
rand_food(foot_turtle, 2.5)

def turtle_forward(my_turtle, isClear, stampList):
    my_turtle = my_turtle
    try:
        my_turtle.forward(FORWARD_PX)
    except Exception:
        del my_turtle
    stampID = my_turtle.stamp()  # stampID开始是6, 每次加2
    pos_x_y_stampId = list(my_turtle.pos()) + [stampID]
    stampList.append(pos_x_y_stampId)
    if is_eat(my_turtle, foot_turtle):  # 如果吃到了静止的食物
        eatMusic.play()
        isClear = False 
        rand_food(foot_turtle, 2.5)
    if movefood is not None and is_eat(my_turtle, movefood):  # 如果吃到了移动的食物
        eatMusic.play()
        isClear = False
    if isClear and len(stampList):
        my_turtle.clearstamp(stampList.pop(0)[2])
    is_border(my_turtle, stampList)  # 是否触碰到了边界
    # -------- 是否咬到了对方的尾部
    if my_turtle.direction == "left":  
        ate_tail_func(t1stampList, my_turtle, t2stamplist)
    elif my_turtle.direction == "right":  # 向右的是玩家一
        ate_tail_func(t2stamplist, my_turtle, t1stampList)
    # --------
    time.sleep(0.1)
    if movefood is not None:
        # 随机移动食物
        rand_food(movefood, 4)

def ate_tail_func(turtle_stampList, my_turtle, my_stampList):  # 咬到对方尾部
    for t_pos in turtle_stampList:
            t_dis = my_turtle.distance(t_pos[0], t_pos[1])
            if t_dis < 40:  # 表示咬到了
                ate_tail.play()
                for _ in range(len(turtle_stampList)//2):
                    if len(my_stampList) > 2:
                        my_turtle.clearstamp(my_stampList.pop(0)[2]) 
                move()


def move():
    global movefood
    if movefood is None:
        movefood = turtle.Turtle()
        movefood.up()
        movefood.speed(0)
        movefood.shape("GreedySnake/8_.gif")

def is_eat(my_turtle, other):
    # 检查与其它(海龟/食物)的距离, 如果吃到了, 返回布尔值True
    dis = my_turtle.distance(other)
    if dis < 40 :
        return True
    return False

def is_border(my_turtle, stampList):
    # my_turtle是否触碰到了边界
    posX, posY = my_turtle.pos()
    posX = abs(posX)
    posY = abs(posY)
    if posX > turtle.window_width()/2  or posY > turtle.window_height()/2:
        # 触碰到边界
        border.play()
        for _ in range(len(stampList)//2):
            my_turtle.clearstamp(stampList.pop(0)[2])
        my_turtle.home()
        if my_turtle.direction == "left":
            my_turtle.left(180)

def forward_always(my_turtle, isClear, stamplist):
    while True:
        time.sleep(0.5)
        turtle_forward(my_turtle, isClear, stamplist)



###############################  玩家一  t1
t1 = turtle.Turtle()
turtle.title("贪吃蛇-海龟版")
t1.up()
t1.direction = "right"  # t1的方向
turtle.register_shape("GreedySnake/1.gif")
t1.shape("GreedySnake/1.gif")
t1.speed(0)
def turtle1_left():
    t1.left(90)
    time.sleep(0.5)
def turtle1_right():
    t1.right(90)
    time.sleep(0.5)
for _ in range(4):
    turtle_forward(t1, False, t1stampList)
threading.Thread(target=forward_always, args=(t1, True, t1stampList), daemon=True).start()

#################################


######################  玩家二 t2
t2 = turtle.Turtle()
t2.up()
t2.direction = "left"  # t2的默认方向
turtle.register_shape("GreedySnake/6.gif")
t2.shape("GreedySnake/6.gif")
t2.left(180)
t2.speed(0)
def turtle2_left():
    t2.left(90)
    time.sleep(0.5)
def turtle2_right():
    t2.right(90)
    time.sleep(0.5)
for _ in range(4):
    turtle_forward(t2, False, t2stamplist)
threading.Thread(target=forward_always, args=(t2, True, t2stamplist), daemon=True).start()


######################
# 玩家一 使用 a d
turtle.onkey(turtle1_left, 'Left')
turtle.onkey(turtle1_right, 'Right')
# 玩家二 使用 方向键
turtle.onkey(turtle2_left, "a")
turtle.onkey(turtle2_right, "d")


turtle.listen()

def play_bgm():
    while True:
        bgm.play()
        time.sleep(99)
threading.Thread(target=play_bgm, daemon=True).start()
turtle.mainloop()
上一篇:Python海龟绘图,画数码晶体管日期 (北理工Python课上代码,加入时分秒)


下一篇:《Python海龟宝典》简介