准备步骤
项目开发使用【Mu 编辑器】
1.新建项目,并导入游戏图片
游戏编写
1.创建场景
SIZE = 15 # 每个格子的大小
WIDTH = SIZE * 30 # 游戏场景总宽度
HEIGHT = SIZE * 30 # 游戏场景总高度
def draw():
screen.fill((255,255,255)) # 设置背景色为白色
运行游戏,可见一个简单的场景被绘制出来
2.创建主角
snake_head = Actor("snake_head",(30, 30)) # 绘制蛇头图标,初始坐标为(30,30)
def draw():
screen.fill((255,255,255))
snake_head.draw() # 绘制蛇头
运行后,场景中可见多了一个蛇头图标
3.移动蛇头
direction = "R" # 蛇头初始移动方向
counter = 0 # 循环标识,控制蛇头位置变更频率
# 监测按下的按键
def check_keys():
global direction
# ←键被按下,且当前方向不为向右
if keyboard.left and direction != "R":
direction = "L"
# →键被按下,且当前方向不为向左
elif keyboard.right and direction != "L":
direction = "R"
# ↑键被按下,且当前方向不为向下
elif keyboard.up and direction != "D":
direction = "U"
# ↓键被按下,且当前方向不为向上
elif keyboard.down and direction != "U":
direction = "D"
# 蛇头移动位置逻辑
def update_snake():
global counter
counter += 1
# 每执行10次update函数,才执行一次下方代码,减缓蛇头位置变更速度
if counter < 10:
return
else:
counter = 0
# 蛇头移动逻辑,改变蛇头位置实现移动效果
if direction == "L":
snake_head.x -= SIZE
elif direction == "R":
snake_head.x += SIZE
elif direction == "U":
snake_head.y -= SIZE
elif direction == "D":
snake_head.y += SIZE
def update():
check_keys()
update_snake()
此刻开始游戏,蛇头就会开始移动,按下方向键,便会改变蛇头移动方向
可使用angle属性,控制图标翻转,实现蛇头朝向效果
# 监测按下的按键
def check_keys():
global direction
# ←键被按下,且当前方向不为向右
if keyboard.left and direction != "R":
direction = "L"
snake_head.angle = 0
# →键被按下,且当前方向不为向左
elif keyboard.right and direction != "L":
direction = "R"
snake_head.angle = 180
# ↑键被按下,且当前方向不为向下
elif keyboard.up and direction != "D":
direction = "U"
snake_head.angle = 90
# ↓键被按下,且当前方向不为向上
elif keyboard.down and direction != "U":
direction = "D"
snake_head.angle = -90
4.添加食物
food = Actor("snake_food")
# 在窗口内生成随机坐标,作为食物出现的位置
food.x = random.randint(2,WIDTH // SIZE - 2) * SIZE
food.y = random.randint(2,HEIGHT // SIZE - 2) * SIZE
def draw():
screen.fill((255,255,255))
snake_head.draw()
food.draw() # 绘制食物
此时运行游戏,窗口中会随机生成食物,但蛇头触碰,并不会被吃掉
5.吃食物
length = 1 # 贪吃蛇当前的初始长度
body = [] # 贪吃蛇蛇身各部位位置,不含蛇头
# draw函数中添加蛇身绘制方法
def draw():
screen.fill((255,255,255))
snake_head.draw()
food.draw()
# 通过循环列表绘制出所有蛇身
for b in body:
b.draw()
# 蛇头移动位置逻辑中增加蛇身移动逻辑
def update_snake():
global counter
counter += 1
if counter < 10:
return
else:
counter = 0
# 如果蛇身数量等于蛇的总长度,则移除列表记录的第一个蛇身,实际是移除蛇尾
if len(body) == length:
body.remove(body[0])
# 在列表后追加当前蛇头的坐标,用于绘制新的蛇身;配合上面删除实现蛇身位置变更效果
body.append(Actor("snake_body",(snake_head.x, snake_head.y)))
if direction == "L":
snake_head.x -= SIZE
elif direction == "R":
snake_head.x += SIZE
elif direction == "U":
snake_head.y -= SIZE
elif direction == "D":
snake_head.y += SIZE
# 吃食物逻辑
def eat_food():
global length
# 如果当前食物坐标与蛇头坐标位置重叠
if food.x == snake_head.x and food.y == snake_head.y:
# 在窗口内随机坐标位置重新生成食物
food.x = random.randint(2,WIDTH // SIZE - 2) * SIZE
food.y = random.randint(2,HEIGHT // SIZE - 2) * SIZE
length += 1 # 每吃一个食物,贪吃蛇长度+1
# 将eat_food方法写入update中
def update():
check_keys()
update_snake()
eat_food()
6.游戏结束判定
finished = False # 游戏结束标识
# draw函数中添加失败弹窗
def draw():
screen.fill((255,255,255))
snake_head.draw()
food.draw()
for b in body:
b.draw()
# 绘制失败提示图像
if finished:
screen.draw.text("Game Over!",center=(WIDTH // 2,HEIGHT // 2),fontsize = 50,color = "red")
# 检测游戏是否结束
def check_gameover():
global finished
# 如果蛇头的位置超出窗口,则判定失败
if snake_head.left < 0 or snake_head.right > WIDTH or snake_head.top < 0 or snake_head.bottom > HEIGHT:
finished = True
# 遍历蛇身,判断是否存在与蛇头重叠的蛇身,有,则判定失败
for n in range(len(body) - 1):
if(body[n].x == snake_head.x and body[n].y == snake_head.y):
finished = True
# update函数中调用检测方法
def update():
# 如果游戏已结束,则不再更新游戏,即暂停游戏
if finished:
return
check_gameover()
check_keys()
eat_food()
update_snake()
运行游戏后,当蛇头碰到蛇身或墙壁,则会暂停游戏,弹窗游戏失败提示语
完整代码
import random
SIZE = 15 # 每个格子的大小
WIDTH = SIZE * 30 # 游戏场景总宽度
HEIGHT = SIZE * 30 # 游戏场景总高度
direction = "R" # 蛇头初始移动方向
counter = 0 # 循环标识
snake_head = Actor("snake_head",(30, 30)) # 绘制蛇头图标,初始坐标为(30,30)
length = 1 # 贪吃蛇当前的初始长度
body = [] # 贪吃蛇蛇身各部位位置,不含蛇头
finished = False # 游戏结束标识
food = Actor("snake_food")
# 在窗口内生成随机坐标,作为食物出现的位置
food.x = random.randint(2,WIDTH // SIZE - 2) * SIZE
food.y = random.randint(2,HEIGHT // SIZE - 2) * SIZE
def draw():
screen.fill((255,255,255)) # 设置背景色为白色
snake_head.draw() # 绘制蛇头
food.draw() # 绘制食物
# 通过循环列表绘制出所有蛇身
for b in body:
b.draw()
# 绘制失败提示图像
if finished:
screen.draw.text("Game Over!",center=(WIDTH // 2,HEIGHT // 2),fontsize = 50,color = "red")
# 监测按下的按键
def check_keys():
global direction
# ←键被按下,且当前方向不为向右
if keyboard.left and direction != "R":
direction = "L"
snake_head.angle = 180
# →键被按下,且当前方向不为向左
elif keyboard.right and direction != "L":
direction = "R"
snake_head.angle = 0
# ↑键被按下,且当前方向不为向下
elif keyboard.up and direction != "D":
direction = "U"
snake_head.angle = 90
# ↓键被按下,且当前方向不为向上
elif keyboard.down and direction != "U":
direction = "D"
snake_head.angle = -90
# 贪吃蛇移动位置各部位变化逻辑
def update_snake():
global counter
counter += 1
# 每执行10次update函数,才执行一次下方代码,减缓蛇头位置变更速度
if counter < 10:
return
else:
counter = 0
# 如果蛇身数量等于蛇的总长度,则移除列表记录的第一个蛇身,实际是移除蛇尾
if len(body) == length:
body.remove(body[0])
# 在列表后追加当前蛇头的坐标,用于绘制新的蛇身;配合上面删除实现蛇身位置变更效果
body.append(Actor("snake_body",(snake_head.x, snake_head.y)))
# 蛇头移动逻辑,改变蛇头位置实现移动效果
if direction == "L":
snake_head.x -= SIZE
elif direction == "R":
snake_head.x += SIZE
elif direction == "U":
snake_head.y -= SIZE
elif direction == "D":
snake_head.y += SIZE
# 吃食物
def eat_food():
global length
# 如果当前食物坐标与蛇头坐标位置重叠
if food.x == snake_head.x and food.y == snake_head.y:
# 在窗口内随机坐标位置重新生成食物
food.x = random.randint(2,WIDTH // SIZE - 2) * SIZE
food.y = random.randint(2,HEIGHT // SIZE - 2) * SIZE
length += 1 # 每吃一个食物,贪吃蛇长度+1
# 检测游戏是否结束
def check_gameover():
global finished
# 如果蛇头的位置超出窗口,则判定失败
if snake_head.left < 0 or snake_head.right > WIDTH or snake_head.top < 0 or snake_head.bottom > HEIGHT:
finished = True
# 遍历蛇身,判断是否存在与蛇头重叠的蛇身,有,则判定失败
for n in range(len(body) - 1):
if(body[n].x == snake_head.x and body[n].y == snake_head.y):
finished = True
def update():
# 如果游戏已结束,则不再更新游戏,即暂停游戏
if finished:
return
check_gameover()
check_keys()
eat_food()
update_snake()