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

server/2024/10/18 18:27:24/

拓展上一项目【Python游戏开发】贪吃蛇

实现穿墙效果

python"># 检测游戏是否结束
def check_gameover():global finished# 移除蛇头位置超过窗口判断for n in range(len(body) - 1):if(body[n].x == snake_head.x and body[n].y == snake_head.y):finished = True     
# 状态检测
def check_status():# 如果蛇头的位置超出窗口,则修改其对应坐标为另一边if snake_head.x - SIZE < 0 :snake_head.x = WIDTH - SIZEelif snake_head.x + SIZE > WIDTH:snake_head.x = SIZEelif snake_head.y - SIZE < 0:snake_head.y = HEIGHTelif snake_head.y + SIZE > HEIGHT:snake_head.y = SIZE

运行游戏,当蛇头经过墙壁时,会从另一端出现

在这里插入图片描述

游戏胜利判定

python">failed = False                                      # 游戏胜利标识
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")# 绘制胜利提示图像if failed:screen.draw.text("Failed!",center=(WIDTH // 2,HEIGHT // 2),fontsize = 50,color = "red")
# 检测游戏是否结束
def check_gameover():global finishedglobal failed# 如果蛇身长度大于等于10,则游戏胜利if len(body) >= 10:failed = Truefor 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 or failed:returncheck_gameover()check_keys()eat_food()update_snake()check_status()

点击间隔

运行游戏时,如果蛇头方向向左移动(←),正常情况下按“→”键是无效的,但如果玩家在很短的时间内按“↑”再按“→”键,就会出现蛇头来不及向上移动,就改变为向右移动的情况,导致蛇头直接与蛇身相撞;

为避免该类问题,我们可以设置最小点击间隔,避免快速点击按键的情况出现

python">start_time = 0                                      # 初始点击时间
# 不用check_keys函数,改为使用内置的on_key_down函数
def on_key_down(key):global direction# 在间隔时间内,则return不执行键盘事件if not check_click_interval(time.time()):return# ←键被按下,且当前方向不为向右if key == keys.LEFT and direction != "R":direction = "L"snake_head.angle = 180# →键被按下,且当前方向不为向左elif key == keys.RIGHT and direction != "L":direction = "R"snake_head.angle = 0# ↑键被按下,且当前方向不为向下elif key == keys.UP and direction != "D":direction = "U"snake_head.angle = 90# ↓键被按下,且当前方向不为向上elif key == keys.DOWN and direction != "U":direction = "D"snake_head.angle = -90
# 点击间隔判定        
def check_click_interval(click_time,interval_time = 0.2):global start_timeisAccord = False# 如果上一次点击间隔与记录的上次点击时间相差大于间隔限制时间,则修改标识为True,并更新start_timeif click_time - start_time >= interval_time:start_time = click_timeisAccord = Truereturn isAccord
def update():if finished or failed:returncheck_gameover()# 移除check_keys# check_keys()eat_food()update_snake()check_status()

完整代码

python">import random
import time
SIZE = 15                                           # 每个格子的大小
WIDTH = SIZE * 30                                   # 游戏场景总宽度
HEIGHT = SIZE * 30                                  # 游戏场景总高度
direction = "R"                                     # 蛇头初始移动方向
counter = 0                                         # 循环标识
snake_head = Actor("snake_head",(30, 30))           # 绘制蛇头图标,初始坐标为(30,30)
length = 1                                          # 贪吃蛇当前的初始长度
MAX_LENGTH = 20                                     # 贪吃蛇最长长度(胜利条件)
body = []                                           # 贪吃蛇蛇身各部位位置,不含蛇头
finished = False                                    # 游戏结束标识
failed = False                                      # 游戏胜利标识
start_time = 0                                      # 初始点击时间
INTERVAL_TIME = 0.1                                 # 点击间隔           food = Actor("snake_food")
# 在窗口内生成随机坐标,作为食物出现的位置
food.x = random.randint(2,WIDTH // SIZE - 2) * SIZE
food.y = random.randint(2,HEIGHT // SIZE - 2) * SIZEdef 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")# 绘制胜利提示图像if failed:screen.draw.text("Failed!",center=(WIDTH // 2,HEIGHT // 2),fontsize = 50,color = "red")# 不用check_keys函数,改为使用内置的on_key_down函数
def on_key_down(key):global direction# 在间隔时间内,直接returnif not check_click_interval(time.time()):return# ←键被按下,且当前方向不为向右if key == keys.LEFT and direction != "R":direction = "L"snake_head.angle = 180# →键被按下,且当前方向不为向左elif key == keys.RIGHT and direction != "L":direction = "R"snake_head.angle = 0# ↑键被按下,且当前方向不为向下elif key == keys.UP and direction != "D":direction = "U"snake_head.angle = 90# ↓键被按下,且当前方向不为向上elif key == keys.DOWN and direction != "U":direction = "D"snake_head.angle = -90# 贪吃蛇移动位置各部位变化逻辑
def update_snake():global countercounter += 1# 每执行10次update函数,才执行一次下方代码,减缓蛇头位置变更速度if counter < 10:returnelse: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 -= SIZEelif direction == "R":snake_head.x += SIZEelif direction == "U":snake_head.y -= SIZEelif 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) * SIZEfood.y = random.randint(2,HEIGHT // SIZE - 2) * SIZElength += 1                                 # 每吃一个食物,贪吃蛇长度+1# 检测游戏是否结束
def check_gameover():global finishedglobal failed# 如果蛇身长度大于等于10,则游戏胜利if len(body) >= MAX_LENGTH:failed = 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 check_status():# 如果蛇头的位置超出窗口,则修改其对应坐标为另一边if snake_head.x - SIZE < 0 :snake_head.x = WIDTH - SIZEelif snake_head.x + SIZE > WIDTH:snake_head.x = SIZEelif snake_head.y - SIZE < 0:snake_head.y = HEIGHT - SIZEelif snake_head.y + SIZE > HEIGHT:snake_head.y = SIZE# 点击间隔判定        
def check_click_interval(click_time):global start_timeisAccord = Falseif click_time - start_time >= INTERVAL_TIME:start_time = click_timeisAccord = Truereturn isAccorddef update():# 如果游戏已结束,则不再更新游戏,即暂停游戏 if finished or failed:returncheck_gameover()eat_food()update_snake()check_status()

http://www.ppmy.cn/server/128136.html

相关文章

M3u8视频由手机拷贝到电脑之后,通过potplayer播放报错找不到文件地址怎么解决?

该文章前面三节主要介绍M3u8视频是什么&#xff0c;视频播放错误(找不到地址)的解决方法在后面 M3U8是一种多媒体播放列表文件格式&#xff0c;主要用于流媒体播放。 一、文件格式特点 1. 文本文件&#xff1a;M3U8是一个采用 UTF-8 编码的文本文件&#xff0c;这意味着它可…

使用 Python 遍历文件夹

要解决这个问题&#xff0c;使用 Python 的标准库可以很好地完成。我们要做的是遍历目录树&#xff0c;找到所有的 text 文件&#xff0c;读取内容&#xff0c;处理空行和空格&#xff0c;并将处理后的内容合并到一个新的文件中。 整体思路&#xff1a; 遍历子目录&#xff1…

尝试从 http://pypi.doubanio.com/simple 这个索引源安装 webdriver 时出现了问题

问题如下&#xff1a; WARNING: The repository located at pypi.doubanio.com is not a trusted or secure host and is being ignored. If this repository is available via HTTPS we recommend you use HTTPS instead, otherwise you may silence this warning and allow …

学习资料库系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;观看记录管理&#xff0c;基础数据管理&#xff0c;论坛信息管理&#xff0c;公告信息管理&#xff0c;轮播图信息 微信端账号功能包括&#xff1a;系统首页&#xff0c;阅读资…

基于拥堵模型的轻量级平台公交室内情况监控系统

论文标题&#xff1a;Bus Indoor Situation Monitoring System Based on Congestion Model Using Lightweight Platform 作者信息&#xff1a;Dong Hyun Kim, Yun Seob Kim, 和 Jong Deok Kim* 所属机构&#xff1a;Pusan National University, Department of Computer Scienc…

Linux中环境变量

基本概念 环境变量Environmental variables一般是指在操作系统中用来指定操作系统运行环境一些参数。 我们在编写C、C代码时候&#xff0c;在链接的时候从来不知道我们所链接的动态、静态库在哪里。但是还是照样可以链接成功。生成可执行程序。原因就是相关环境变量帮助编译器…

React响应式数据useState

React响应式数据useState 最近学了React&#xff0c;发现与Vue大有不同&#xff0c;在Vue中实现数据的响应式通过ref()函数&#xff0c;React则是通过useState()函数 使用 语法&#xff1a;const [data, setData] useState(数据) 说明&#xff1a;将数据传给useState()&am…

【Linux】信号知识三把斧——信号的产生、保存和处理

目录​​​​​​​ 1、关于信号的前置知识 1.1.什么是信号&#xff1f; 1.2.为什么要学习信号&#xff1f; 1.3.如何学习信号&#xff1f; 1.4.一些常见的信号 1.5.信号的处理方式 1.6.为什么每一个进程都可以系统调用&#xff1f; 2.信号的产生 2.1.kill命令产生信号…