title: 贪吃蛇
date: 2023-04-18
updated: 2023-04-18
tags: 小游戏
categories: Python
要求
对象:
一条蛇、一个怪物和 一些食物,由一组介于 1 和 9 之间的数字表示,头和尾巴分别以红色和黑色显示 ,而怪物则由 紫色方块显示。 数字是蛇吃的食物
界面:
以下屏幕显示了蛇吃完所有食物后游戏的结局 包括完全伸展的尾巴;状态区域显示的是与怪物的接触次数 以及 以 秒为单位的总游戏时间
画布:
上部状态区域 = 500 (宽) x 80
游戏状态 :
a. 显示蛇的运动(左、右、上、下、暂停),换句话说,最后一个 按下运动键(包括空格键),无论蛇是否在 运动或贝因G受阻。
b. 显示蛇与怪物的身体接触总数。 计数应 基于怪物计时器的运动。 每次重新定位怪物时,它 然后应该检查它是否与蛇的任何部分重叠。
c. 以 秒为单位跟踪经过的总游戏时间。 时间计数器尽快启动 因为游戏开始,只有在游戏结束时才会停止。 换句话说,计数器 当蛇被暂停时不会被阻止。
规则:
食物:
在随机位置显示运动区域内从 1 到 5 的 5 种食物。 这些 数字将始终保持可见,直到它们被蛇吞噬。 当 蛇头越过这些数字之一, 被划过的数字是 被视为已消耗,它将从游戏区域永久删除。 所以,任何 一种食物可以食用一次
一个单位长度,因此尾巴在 完全伸展时将由 5 个方形组成
怪物 :
a、一个固定大小的物体,被编程为 向蛇移动,试图做出 正面碰撞。
b. 启动时,将怪物放置在与蛇保持一定距离的随机位置。
c. 怪物应该以随机的速度移动
蛇:
在游戏开始时,尾巴的长度设置为 5。 一个正方形算作
按下空格蛇暂停,怪物不暂停
游戏内核
通过定时器运动
a. “计时器”是指特定事件以固定间隔发生的频率,在 在这种情况下,事件是蛇或怪物的运动。
b. 使用 单独的 计时器手动刷新蛇和怪物的移动 一. 关闭 内置的自动屏幕刷新
c. 设置适当的计时器速率,例如不超过 0.2 秒
模块
仅使用标准 python 模块
制作思路
界面:turtle
定时器:time
随机数:random
学习路线
界面
使用turtle,找看看turtle的刷新机制
划分游戏区域、游戏状态、边缘
turtle 键盘监听
对象与动作构建
创建蛇、怪物、食物类
turtle用到的方法
Python中的turtle.onkey()函数|极客教程 (geek-docs.com)
turtle .ontimer()
import turtle
import time
import random
global pre_direction,snake,snake_hide,monster,head,food,pen,pen1,num_array,food_num,wn,contact,delay,num_str,count,pre_x,pre_y,starttime ,endtime, last_length,time_eated,time_win
## 怪物
monster = turtle.Turtle()
monster.shape("square")
monster.color("purple")
monster.penup()
monster.goto(200, 200)
monster.direction = "Stop"
pre_direction = "Stop"
monster.speed(1)
##b标题画笔
pen = turtle.Turtle()
pen.speed(0)
pen.shape("square")
pen.color("black")
pen.penup()
pen.hideturtle() # 隐藏笔迹
pen.goto(0, 210)
pen.write("Score : 0 High Score : 0", align="center",
font=("candara", 24, "bold"))
#画布画笔
pen1 = turtle.Turtle()
pen1.speed(0)
pen1.shape("square")
pen1.color("black")
pen1.penup()
pen1.hideturtle() # 隐藏笔迹
pen1.goto(-250, 210)
pen1.pendown()
pen1.forward(500)
pen1.right(90)
pen1.forward(500)
pen1.right(90)
pen1.forward(500)
pen1.right(90)
pen1.forward(580)
pen1.right(90)
pen1.forward(500)
pen1.right(90)
pen1.forward(580)
#主窗体
starttime = time.time()
endtime = time.time()
count = 3
stop_flag = 0
contact = 5
delay = 0.1
high_contact = 0
# x = 0
# y = 0
wn = turtle.Screen() ##画笔对象
wn = turtle.Screen()
wn.title("Snake Game")
wn.bgcolor("white")
# the width and height can be put as user's choice
wn.setup(width=580, height=660)
wn.tracer(0)
##蛇
def group():
if head.direction != "down":
head.direction = "up"
def godown():
global monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count
if head.direction != "up":
head.direction = "down"
def goleft():
global monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count
if head.direction != "right":
head.direction = "left"
def goright():
global monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count
if head.direction != "left":
head.direction = "right"
def stop():
global monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count,pre_direction
# print(pre_direction)
if head.direction != "stop":
pre_direction = head.direction
head.direction = "stop"
return
if head.direction == "stop":
head.direction = pre_direction
print("之前动作",pre_direction)
print("尝试恢复",head.direction)
return
# 食物
def del_num():
global monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count
##关键代码,解决无法删除列表中某个值的问题
if len(num_array) > 0:
for i in reversed(range(len(num_array))):
if num_array[i] == num_str:
del num_array[i]
# print(num_array[i])
def move():
global monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count
if head.direction == "up":
y = head.ycor()
head.sety(y + 20)
if head.direction == "down":
y = head.ycor()
head.sety(y - 20)
if head.direction == "left":
x = head.xcor()
head.setx(x - 20)
if head.direction == "right":
x = head.xcor()
head.setx(x + 20)
#设置监听
wn.listen()
wn.onkeypress(group, "w") # if food_num == 0:
wn.onkeypress(stop," ")
wn.onkeypress(godown, "s")
wn.onkeypress(goleft, "a")
wn.onkeypress(goright, "d")
def staus_upgrade():
global monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count,starttime ,endtime
pen.clear()
endtime = time.time()
time_c = int(endtime - starttime)
# print(time_c)
pen.write("Contact: {} Time: {} Motion {} ".format(
contact, time_c, head.direction), align="center", font=("candara", 18, "bold"))
def food_born():
global food_num,foods,num_array,num_str,foods,num_array1,num_food
food_x_array = []
for i in range(0,food_num,1):
food_x_array.append(random.randrange(-200,200))
food_y_array = []
for i in range(0,food_num,1):
food_y_array.append(random.randrange(-270,200))
#随机加载 1~ 5个食物
foods= []
for i in range(0,food_num,1):
print("food_num", food_num, "num_array", num_array)
food = turtle.Turtle()
food.speed(0)
food.shape("square")
food.color("black")
food.penup()
food.hideturtle() # 隐藏海龟
food.goto(food_x_array[i], food_y_array[i])
# num_str = random.choice(num_array)
num_str =str(num_array[i])
up_or_down = random.choice([0,1])
if food_num == 1:
up_or_down= 0
print("up_or_down",up_or_down)
if up_or_down == 0:
print("food_generated",num_str)
food.write(num_str, align="center",
font=("candara", 24, "bold"))
else:
pass
foods.append(food)
# time.sleep(0.05)
def If_Over():
global foods
global collision_flag,time_eated, time_win, monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count, starttime, endtime,last_length
if food_num == 0:
# food.clear()
print("here")
time_win = time.time()
print(int(time_win - time_eated))
if int(time_win - time_eated) > 2:
for index in range(0,len(foods),1):
foods[index].clear()
time.sleep(0.2)
kill_food()
foods= []
time.sleep(1)
head.goto(1000, 1000)
head.direction = "stop"
head.clear()
for segment in segments:
segment.goto(1000, 1000)
segments.clear()
contact = 5
delay = 0.1
# pen1.pen.clear()
pen.write("Contact: {} Time: {} Motion {} ".format(0, 0, 0), align="center", font=("Arial", 24, "bold"))
init()
if collision_flag or head.xcor() > 250 or head.xcor() < -250 or head.ycor() > 210 or head.ycor() < -290:
# food.clear()
kill_food()
time.sleep(1)
head.goto(1000, 1000)
head.direction = "stop"
head.clear()
monster.goto(200,200)
for segment in segments:
segment.goto(1000, 1000)
segments.clear()
contact = 5
delay = 0.1
# pen1.pen.clear()
pen.write("Contact: {} Time: {} Motion {} ".format(0, 0, 0), align="center",font=("Arial", 24, "bold"))
init()
def kill_food():
global food_num,foods
# for i in range(0,food_num):
# foods[i].clear()
if len(foods)>0 :
for i in range(0,len(foods)):
foods[i].goto(3000,3000)
foods[i].clear()
foods = []
def food_eated():
global snake_hide,monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count, last_length,time_eated
global foods,food_x_array,food_y_array,num_array1
for index in reversed(range(0,len(foods))):
# print("index--------------------------",index)
if head.distance(foods[index]) < 20:
if food_num > 0:
food_num -= 1
# print("food_num",food_num)
# print("index......",index,"num_aray1",num_array1)
foods[index].clear()
time.sleep(0.1)
kill_food()
# del foods[index]
time_eated = time.time()
if int(num_array[index]) > 0:
snake_hide += int(num_array[index])
for i in range(int(num_array[index])):
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
# new_segment.color(
# "black") # tail colour
new_segment.color("black")
new_segment.penup()
new_segment.setx(1000)
new_segment.sety(1000)
# new_segment.goto(x, y)
segments.append(new_segment)
print("len seg", len(segments))
contact += int(num_array[index])
print("clear", num_array[index])
del num_array[index]
# num_str ='0'
if food_num > 0:
food_born()
print("food_num ", food_num)
# del_num()
# if food_num > 0:
# foods[index].write(num_str, align="center",
# font=("candara", 20, "bold"))
delay -= 0.001
staus_upgrade()
def seg_move():
global monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count,pre_x,pre_y
##身体第一块跑向头
if head.direction != "stop":
if len(segments) > 0:
# pre_seg = turtle.Turtle()
# pre_seg.shape("square")
# # new_segment.color(
# # "black") # tail colour
# pre_seg.color(random.choice(["green", "red", "blue", "black", "yellow", "pink"]))
# pre_seg.penup()
pre_x = segments[0].xcor()
pre_y = segments[0].ycor()
# pre_seg.goto(x, y)
x = head.xcor()
y = head.ycor()
segments[0].goto(x, y)
for index in range(len(segments) - 1, 0, -1):
# for index in range(0,len(segments)-1, 1)
if index == 1:
segments[1].goto(pre_x, pre_y)
return
x = segments[index - 1].xcor()
y = segments[index - 1].ycor()
segments[index].goto(x, y)
def chase():
global monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count
x = head.xcor()
y = head.ycor()
x1 = monster.xcor()
y1 = monster.ycor()
# if abs(y1-y) > abs(x1-x):
# if y1 < y:
# monster1.monster.sety(y1 + 20)
# else:
# .sety(y1 - 20)
# else:
# if x1 < x:
# .setx(x1 + 20)
# else:
# .setx(x1 - 20)
# wn.tracer(n=5, delay=0)
if abs(y1 - y) > abs(x1 - x):
if y1 < y:
monster.seth(90)
monster.forward(20)
else:
monster.seth(270)
monster.forward(20)
else:
if x1 < x:
monster.seth(0)
monster.forward(20)
else:
monster.seth(180)
monster.forward(20)
def if_chased():
global snake,collision_flag,segments,head,monster
# seg = segments
# seg.append(head)
for index in range(0,len(snake),1):
if snake[index].distance(monster) <20:
time.sleep(1)
head.goto(0, 0)
head.direction = "stop"
print("here..........qqqq.....................")
colors = random.choice(['red', 'blue', 'green'])
shapes = random.choice(['square', 'circle'])
for segment in segments:
segment.goto(1000, 1000)
segment.clear()
collision_flag = 1
def if_head_runto_body():
global collision_flag,segments
for segment in segments:
if segment.distance(head) < 20 and snake_hide == 0:
time.sleep(1)
head.goto(0, 0)
head.direction = "stop"
print("here...............................")
colors = random.choice(['red', 'blue', 'green'])
shapes = random.choice(['square', 'circle'])
for segment in segments:
segment.goto(1000, 1000)
segment.clear()
collision_flag = 1
contact = 0
delay = 0.1
def init():
global monster, head, food, pen, pen1, num_array, food_num, wn, contact, delay, num_str, count, starttime , endtime
global segments,snake_hide,collision_flag,food_x_array ,food_y_array ,foods,num_array1,count2
# 初始化
count2 = 10
contact = 5
collision_flag = 0
starttime = time.time()
endtime = time.time()
segments = []
# food.clear()
# num_array = ['1', '2', '3', '4', '5']
# food_num = 5
# 蛇
head = turtle.Turtle()
head.shape("square")
head.color("red")
head.penup()
head.goto(0, 0)
head.direction = "stop"
pre_direction = "stop"
segments = []
# 食物
num_array = ['1', '2', '3', '4', '5']
num_array1 = ['1', '2', '3', '4', '5']
food_num = 5
food_born()
snake_hide = 5
for i in range(5):
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
# new_segment.color(
# "black") # tail colour
new_segment.color("black")
new_segment.penup()
new_segment.setx(1000)
new_segment.sety(1000)
# new_segment.goto(x, y)
segments.append(new_segment)
def Game_Start():
global count2,snake,snake_hide,monster,head,food,pen,pen1,num_array,food_num,wn,contact,delay,num_str,count,last_length,segments
## 蛇走n步 ,怪物走 1 步
wn.update()
# food.write(num_str, align="center",
# font=("candara", 24, "bold"))
count -= 1
if count == 0:
count = random.choice([ 2, 3, 4])
chase()
count2 -= 1
if count2 == 0 :
count2 = 50
kill_food()
food_born()
##游戏结束
food_eated()
snake = []
snake.append(head)
for i in range(0,len(segments),1):
snake.append(segments[i])
If_Over()
# len(segments)
seg_move()
move()
if snake_hide > 0 and head.direction != "stop":
snake_hide -= 1
time.sleep(0.05)
# print("hide'''''",snake_hide)
# Checking for head collisions with body segments
if_head_runto_body()
if_chased()
staus_upgrade()
wn.ontimer(Game_Start, 100)
init()
seg_move()
Game_Start()
wn.mainloop()
# if __name__ == "main":
# Game_Start()
# wn.mainloop()