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

拓展上一项目【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

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

在这里插入图片描述

游戏胜利判定

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()

点击间隔

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

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

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()

完整代码

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.xdnf.cn/news/1555076.html

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

相关文章

涉案财务管理系统架构二—交警相关系统——未来之窗行业应用跨平台架构

一、涉案财务保管流程 二、涉案财务返回流程 三、阿雪技术观 拥抱开源与共享&#xff0c;见证科技进步奇迹&#xff0c;畅享人类幸福时光&#xff01; 让我们积极投身于技术共享的浪潮中&#xff0c;不仅仅是作为受益者&#xff0c;更要成为贡献者。无论是分享自己的代码、撰写…

案例-任务清单

文章目录 效果展示初始化面演示画面 代码区 效果展示 初始化面 演示画面 任务清单 代码区 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, in…

Meta推出Movie Gen 旗下迄今最先进的视频生成AI模型

Meta 今天发布了 MovieGen 系列媒体基础AI模型&#xff0c;该模型可根据文本提示生成带声音的逼真视频。 MovieGen 系列包括两个主要模型&#xff1a; MovieGen Video 和 MovieGen Audio。 MovieGen Video 是一个具有 300 亿个参数的变换器模型&#xff0c;可根据单个文本提示生…

蛋白质结构中原子坐标转换

在蛋白质结构分析中,原子坐标经过旋转矩阵和平移向量的转换是常见操作。一般情况下,假设一个原子在结构 A 中的坐标为 (x, y, z),在经过旋转矩阵 u 和平移向量 t 的变换后,得到新的坐标 (X, Y, Z)。然后,再将新的坐标反向映射回原始坐标系。 基本数学公式 1. 变换公式:…

AVL树的创建与检测

个人主页&#xff1a;敲上瘾-CSDN博客 个人专栏&#xff1a;游戏、数据结构、c语言基础、c学习、算法 目录 一、什么是AVL树&#xff1f; 二、平衡因子 1、什么是平衡因子&#xff1f; 2、平衡因子如何更新&#xff1f; 三、单旋 1、左单旋 ​编辑 2、右单旋 四、双旋…

c++结构体嵌套

没有很听懂这个课 有点乱了、 // // Created by 徐昌真 on 2024/10/5. // #include <iostream> using namespace std; int main() {struct Point{ //定义一个叫做point的结构体double x, y;};struct Radius{Point pt; //嵌套point结构体在radius结构体里面 把他名字定…

从介质失效看互联网时代的信息过载

来读一篇文章&#xff1a;90年代的硬盘已大规模变砖&#xff0c;没啥好担心的&#xff0c;好事。 结合我两年前的粗浅认知 互联网时代无信息&#xff0c;按照 “动” 的观念看&#xff0c;当信息越来越多&#xff0c;信息密度越来越大时&#xff0c;信息的寿命就会越来越短&am…

k8s实战-1

k8s实战-1 一、资源创建方式1.命令行2.yaml 二、命名空间三、Pod总结 一、资源创建方式 1.命令行 就是直接通过命令的方式创建&#xff0c;比如我要创建namespace&#xff0c; kubectl create namespace hello删除&#xff1a; kubectl delete -f hello2.yaml 简单来说&am…

分布式事务(Seata-AT模式)

角色说明 TC (Transaction Coordinator) - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。 TM (Transaction Manager) - 事务管理器 定义全局事务的范围:开始全局事务、提交或回滚全局事务。 RM (Resource Manager) - 资源管理器 管理分…

发现一篇瑞芯微RK3588上使用Gstreamer的文章(野火)

1. 前言 最近经常使用英伟达的Orin和瑞芯微RK3588做开发,自己还买了好几块开发板,很多需要自己琢磨,今天忽然发现了一篇文章,意外解决了一些之前的问题,以此作为记录: 文章链接:https://doc.embedfire.com/linux/rk356x/quick_start/zh/latest/lubancat_rk_software_har…

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

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

使用ValueConverters扩展实现枚举控制页面的显示

1、ValueConverters 本库包含了IValueConverter接口的的最常用的实现&#xff0c;ValueConverters用于从视图到视图模型的值得转换&#xff0c;某些情况下&#xff0c;可用进行反向转换。里面有一些抽象类、模板类的定义&#xff0c;可以继承这些类实现一些自己想要实现的功能…

GO网络编程(三):海量用户通信系统1:登录功能

一、准备工作 需求分析 1)用户注册 2)用户登录 3)显示在线用户列表 4)群聊(广播) 5)点对点聊天 6)离线留言 主界面 首先&#xff0c;在项目根目录下初始化mod&#xff0c;然后按照如下结构设计目录&#xff1a; 海量用户通信系统/ ├── go.mod ├── client/ │ ├──…

YOLO11改进|卷积篇|引入全维动态卷积ODConv

目录 一、【ODConv】全维动态卷积1.1【ODConv】卷积介绍1.2【ODConv】核心代码 二、添加【ODConv】卷积2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【ODConv】全维动态卷积 1.1【ODConv】卷积介绍 ODConv利用一种全新的多维注意力机…

操作系统实验之银行算法

一、实验目的 采用高级语言编写一个动态分配系统资源的程序&#xff0c;模拟死锁现象&#xff0c;观察死锁发生的条件&#xff0c;并采用适当的算法&#xff0c;有效地防止死锁的发生。 二、实验内容 本次实验采用银行算法防止死锁的发生。设有3个并发进程共享10个系统资源。在…

无神论文解读之ControlNet:Adding Conditional Control to Text-to-Image Diffusion Models

一、什么是ControlNet ControlNet是一种能够控制模型生成内容的方法&#xff0c;能够对文生图等模型添加限制信息&#xff08;边缘、深度图、法向量图、姿势点图等&#xff09;&#xff0c;在当今生成比较火的时代很流行。 这种方法使得能够直接提供空间信息控制图片以更细粒…

AQS机制详解

案例一 public class AqsThread extends Thread {private Lock lock;public AqsThread(String name, Lock lock) {super(name);this.lock lock;}Overridepublic void run() {lock.lock();try {System.out.println(Thread.currentThread().getName() "running");} …

【LeetCode】每日一题 2024_10_5 完成旅途的最少时间(二分答案)

前言 每天和你一起刷 LeetCode 每日一题~ 大家国庆节快乐呀~ LeetCode 启动&#xff01; 突然发现&#xff0c;国庆的每日一题&#xff0c;不是坐公交就是坐火车&#xff0c;不是坐火车就是做飞机&#xff0c;这就是你的国庆旅游计划吗&#xff01;力扣&#xff01; 题目&a…

图表不会做怎么办?AI一键生成好看图表!

本期教你如何用AI一键生成各种数据图表&#xff01; 本文阅读难度&#xff1a;★☆☆☆☆ 看看别人做的这些图表&#xff0c;是不是挺好看的&#xff1f; 特别是作为接商单的新写手&#xff0c;看到这些&#xff0c;头都大了&#xff0c;该怎么办呢&#xff1f; 不用怕&…

ModuleNotFoundError: No module named ‘package‘

报错&#xff1a; Traceback (most recent call last): File “”, line 198, in run_module_as_main File “”, line 88, in run_code File "D:\python\helloworld.venv\Scripts\pip.exe_main.py", line 4, in File "D:\python\helloworld.venv\Lib\site-pac…