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

news2024/10/6 13:45:23

拓展上一项目【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 - SIZE
    elif snake_head.x + SIZE > WIDTH:
        snake_head.x = SIZE
    elif snake_head.y - SIZE < 0:
        snake_head.y = HEIGHT
    elif snake_head.y + SIZE > HEIGHT:
        snake_head.y = SIZE

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

在这里插入图片描述

游戏胜利判定

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 finished
    global failed
    # 如果蛇身长度大于等于10,则游戏胜利
    if len(body) >= 10:
        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 update():
    # 如果游戏已结束,则不再更新游戏,即暂停游戏 
    if finished or failed:
        return
    check_gameover()
    check_keys()
    eat_food()
    update_snake()
    check_status()

点击间隔

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

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

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_time
    isAccord = False
    # 如果上一次点击间隔与记录的上次点击时间相差大于间隔限制时间,则修改标识为True,并更新start_time
    if click_time - start_time >= interval_time:
        start_time = click_time
        isAccord = True
    return isAccord
def update():
    if finished or failed:
        return
    check_gameover()
    # 移除check_keys
    # check_keys()
    eat_food()
    update_snake()
    check_status()

完整代码

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) * 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")
    # 绘制胜利提示图像
    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
    # 在间隔时间内,直接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 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
    global 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 - SIZE
    elif snake_head.x + SIZE > WIDTH:
        snake_head.x = SIZE
    elif snake_head.y - SIZE < 0:
        snake_head.y = HEIGHT - SIZE
    elif snake_head.y + SIZE > HEIGHT:
        snake_head.y = SIZE

# 点击间隔判定        
def check_click_interval(click_time):
    global start_time
    isAccord = False
    if click_time - start_time >= INTERVAL_TIME:
        start_time = click_time
        isAccord = True
    return isAccord
    
def update():
    # 如果游戏已结束,则不再更新游戏,即暂停游戏 
    if finished or failed:
        return
    check_gameover()
    eat_food()
    update_snake()
    check_status()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2192030.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嘴尚绝卤味:健康美味的双重奏

在当今快节奏的生活中&#xff0c;人们对美食的追求不再仅仅停留于味蕾的满足&#xff0c;更加注重食物的健康与营养。在这一背景下&#xff0c;"嘴尚绝卤味"以其独特的健康理念与精湛的制作工艺&#xff0c;成为了市场上备受瞩目的卤味品牌。本文将从"嘴尚绝卤…

Linux运维01:VMware创建虚拟机

视频链接&#xff1a;05.新建VM虚拟机_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1nW411L7xm/?p14&spm_id_from333.880.my_history.page.click&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.点击“创建虚拟机” 2.选择“自定义&#xff08;高级&#xff0…

15分钟学 Python 第41天:Python 爬虫入门(六)第二篇

Day41&#xff1a;Python爬取猫眼电影网站的电影信息 1. 项目背景 在本项目中&#xff0c;我们将使用 Python 爬虫技术从猫眼电影网站抓取电影信息。猫眼电影是一个知名的电影信息平台&#xff0c;提供了丰富的电影相关数据。通过这个练习&#xff0c;您将深入学习如何抓取动…

小白必看一文彻底搞懂 Transformer(图解+手撕)

Transformers 亮相以来彻底改变了深度学习模型。 今天&#xff0c;我们将揭示 Transformers 背后的核心概念&#xff1a;注意力机制、编码器-解码器架构、多头注意力等等。 通过 Python 代码片段&#xff0c;让你深入了解其原理。 技术交流群 前沿技术资讯、算法交流、求职…

用IMX6UL开发板编写按键输入实验

在之前我们都是讲解如何使用IMX6UL的GPIO输出控制等功能&#xff0c;IMX6U的IO不仅能作为输出&#xff0c;而且也可以作为输入&#xff0c;而我们开发板上具有一个按键&#xff0c;按键肯定是连接了一个IO口的额&#xff0c;我们在这一节将会把IO配置成输入功能&#xff0c;读取…

JAVA基础面试题汇总(持续更新)

1、精确运算场景使用浮点型运算问题 精确运算场景&#xff08;如金融领域计算应计利息&#xff09;计算数字&#xff0c;使用浮点型&#xff0c;由于精度丢失问题&#xff0c;会导致计算后的结果和预期不一致&#xff0c;使用Bigdecimal类型解决此问题&#xff0c;示例代码如下…

Java类的生命周期浅析

知识前提 在了解类的生命周期之前&#xff0c;有必要先了解一下jvm的内存结构。如下所示&#xff1a; 在了解完jvm的内存结构之后&#xff0c;就知道了例如堆区&#xff0c;栈区&#xff0c;常量池和方法区等概念。 也了解到了&#xff0c;编写的代码&#xff0c;是先需要通过…

使用pytdx获取股票信息总结

使用pytdx获取股票相关信息汇总 行情接口标准行情对接总结界面展示性能问题数据可靠性 附录代码 行情接口 pytdx中提供了hq&#xff08;标准行情&#xff09;及exhq&#xff08;扩展市场行情&#xff09;两种接口&#xff0c;扩展市场目前已经失效无法使用。 标准行情 这里只…

4. Getter和Setter注解与lombok

文章目录 1. 什么是Getter和Setter注解2. 什么是lombokjava自带的jar包 3. 从maven仓库里找lombok相关jar包4. 把jar包导入项目另一个jar包导入途径 5. 正式使用注解① 问题② 解决方案提示 6. 如果还想对某个成员变量添加限制怎么办7. 内容出处 1. 什么是Getter和Setter注解 官…

【包教包会】速通LLM《从头开始构建大型语言模型》免费pdf分享

介绍 在当今人工智能技术飞速发展的时代&#xff0c;大型语言模型&#xff08;LLM&#xff09;作为聊天机器人、文本生成和理解等应用的核心&#xff0c;已经成为研究和商业领域的关注焦点。尽管这些模型的应用无处不在&#xff0c;但对于大多数开发者来说&#xff0c;它们的工…

AI正悄然地影响着企业数字化转型

2022年底发布的ChatGPT将人工智能技术上升到了一个新的高度。如今&#xff0c;人工智能正彻底改变数字转型的进程&#xff0c;为企业提供优化运营和提升客户体验的机会。利用算法、数据分析、机器学习等人工智能技术结合企业自身情况&#xff0c;可以推动企业持续创新&#xff…

每日OJ题_牛客_mari和shiny_线性dp_C++_Java

目录 牛客_mari和shiny_线性dp 题目解析 C代码 Java代码 牛客_mari和shiny_线性dp mari和shiny (nowcoder.com) 描述&#xff1a; mari每天都非常shiny。她的目标是把正能量传达到世界的每个角落&#xff01; 有一天&#xff0c;她得到了一个仅由小写字母组成的字…

ElasticSearch 备考 -- Snapshot Restore

一、题目 备份集群下的索引 task&#xff0c;存储快照名称为 snapshot_1 二、思考 这个涉及的是集群的备份&#xff0c;主要是通过创建快照&#xff0c;涉及到以下2步骤 Setp1&#xff1a;注册一个备份 snapshot repository Setp2&#xff1a;创建 snapshot 可以通过两种方…

找生网站方案———未来之窗行业应用跨平台架构

1&#xff09;网站设计方面的考虑 主色调采用于公司深蓝色颜色&#xff0c;网页整体色彩明快、大气、简洁&#xff0c;每个细节均经过精心处 理&#xff0c;网页浏览快速&#xff0c;导航明确清晰。 网页设计要充分考虑网页的整体感觉&#xff0c;每个页面的图片与网站色调的过…

YOLO11改进 | 卷积模块 | 用Ghost卷积轻量化网络【详细步骤】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; Ghost 模块可以作为即插即用组件来升级…

C(十四)while、for、do-while循环综合(一)

uu们&#xff0c;小弟我本科在读&#xff0c;文章我会一直坚持更新下去&#xff0c;包括但不限于C初阶、C进阶、数据结构、C、Linux、MySQL、项目、QT开发、各种算法&#xff08;之后会持续更新&#xff09;&#xff0c;并且站在小白的视角尽可能通俗易懂地把这些写出来&#x…

xss之dom类型

目录 xss关于dom类型 1、闭合方式 2、闭合&#xff0c;直接输入1&#xff0c;成功闭合 上我们的pikachu xss关于dom类型 1、闭合方式 输入123&#xff0c;然后打开f12&#xff0c;审查元素&#xff0c;之前一直没有搞懂为什么要在前面加上个单引号 输入两个双引号&#x…

【STM32开发之寄存器版】(三)-详解NVIC中断

一、前言 STM32F103ZET6具备强大的中断控制能力&#xff0c;其嵌套向量中断控制器(NVIC)和处理器核的接口紧密相连&#xff0c;可以实现低延迟的中断处理和高效地处理晚到的中断。NVIC主要具备以下特性&#xff1a; 68个可屏蔽中断通道(不包含16个Cortex™-M3的中断线)&#xf…

【黑马点评】 使用RabbitMQ实现消息队列——1.Docker与RabbitMQ环境安装

黑马点评中&#xff0c;使用基于Redis的Stream实现消息队列&#xff0c;但是Strema已经不太常用。在此修改为使用RabbitMQ实现消息队列。主要包括RabbitMQ的环境准备&#xff08;Docker的下载与安装&#xff09;以及如何修改黑马点评中的代码。 【黑马点评】使用RabbitMQ实现消…

【Java数据结构】栈 (Stack)

【本节目标】 1. 栈的概念及使用 2. 相关 OJ 题 一、概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last…