【Python游戏开发】贪吃蛇游戏demo

准备步骤

项目开发使用【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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值