[Python] 一个可识别窗口范围的贪吃蛇

news/2025/2/21 20:45:40/文章来源:https://www.cnblogs.com/alfredsun/p/18725873
import curses
import random
import time
import osclass SnakeGame:def __init__(self):# 初始化颜色self.init_colors()self.min_height = 10self.min_width = 30if not self.show_start_screen():raise SystemExit("游戏已取消")# 初始化游戏参数self.init_game()def init_colors(self):self.screen = curses.initscr()curses.start_color()curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)   # 蛇的颜色curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)     # 食物的颜色curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK)  # 分数的颜色curses.init_pair(4, curses.COLOR_CYAN, curses.COLOR_BLACK)    # 提示文字颜色def show_start_screen(self):self.screen.clear()self.screen.keypad(1)curses.noecho()curses.curs_set(0)height, width = self.screen.getmaxyx()# 显示标题title = "贪吃蛇游戏"self.screen.addstr(height//4, (width-len(title))//2, title, curses.color_pair(3) | curses.A_BOLD)# 显示调整窗口提示instructions = ["请调整窗口大小至合适大小",f"最小要求: {self.min_width}x{self.min_height}","当前大小: {}x{}","","按空格键开始游戏","按 Q 退出游戏"]while True:current_height, current_width = self.screen.getmaxyx()# 显示指示信息for i, text in enumerate(instructions):if "当前大小" in text:text = text.format(current_width, current_height)y = height//4 + 2 + iif y < current_height - 1:  # 防止写入最后一行self.screen.addstr(y, (width-len(text))//2, text, curses.color_pair(4))# 检查窗口大小是否合适size_ok = current_height >= self.min_height and current_width >= self.min_widthstatus = "窗口大小合适 ✓" if size_ok else "窗口太小 ✗"status_color = curses.color_pair(1) if size_ok else curses.color_pair(2)self.screen.addstr(height//4 + len(instructions) + 1, (width-len(status))//2, status, status_color | curses.A_BOLD)self.screen.refresh()# 获取用户输入key = self.screen.getch()if key == ord(' ') and size_ok:  # 空格键且窗口大小合适return Trueelif key in (ord('q'), ord('Q')):  # Q键退出return False# 短暂延迟,降低CPU使用率time.sleep(0.1)def init_game(self):# 获取当前窗口大小self.height, self.width = self.screen.getmaxyx()self.screen.clear()self.screen.border(0)# 初始化蛇的位置(在屏幕中央)center_y = self.height // 2center_x = self.width // 2self.snake = [[center_y, center_x], [center_y, center_x-1], [center_y, center_x-2]]# 初始化其他游戏参数self.food = Noneself.generate_food()self.direction = curses.KEY_RIGHTself.score = 0self.speed = 0.1self.paused = Falsedef generate_food(self):while True:self.food = [random.randint(1, self.height-2),random.randint(1, self.width-2)]if self.food not in self.snake:breakdef show_score(self):score_text = f"分数: {self.score} | 按P暂停 | 按Q退出"self.screen.addstr(0, 2, score_text, curses.color_pair(3))def update_screen(self):self.screen.clear()self.screen.border(0)# 显示蛇for pos in self.snake:self.screen.addch(pos[0], pos[1], '#', curses.color_pair(1))# 显示食物self.screen.addch(self.food[0], self.food[1], '*', curses.color_pair(2))# 显示分数和控制说明self.show_score()# 如果游戏暂停,显示暂停信息if self.paused:pause_text = "游戏暂停中 - 按P继续"self.screen.addstr(self.height//2, (self.width-len(pause_text))//2, pause_text, curses.color_pair(4) | curses.A_BOLD)self.screen.refresh()def get_next_position(self):head = self.snake[0].copy()if self.direction == curses.KEY_UP:head[0] -= 1elif self.direction == curses.KEY_DOWN:head[0] += 1elif self.direction == curses.KEY_LEFT:head[1] -= 1elif self.direction == curses.KEY_RIGHT:head[1] += 1return headdef play(self):while True:self.update_screen()# 获取用户输入self.screen.timeout(100)event = self.screen.getch()# 处理暂停if event in (ord('p'), ord('P')):self.paused = not self.pausedcontinue# 处理退出if event in (ord('q'), ord('Q')):break# 如果游戏暂停,跳过其他处理if self.paused:continue# 更新方向if event in [curses.KEY_UP, curses.KEY_DOWN, curses.KEY_LEFT, curses.KEY_RIGHT]:# 防止蛇反向移动if (event == curses.KEY_UP and self.direction != curses.KEY_DOWN) or \(event == curses.KEY_DOWN and self.direction != curses.KEY_UP) or \(event == curses.KEY_LEFT and self.direction != curses.KEY_RIGHT) or \(event == curses.KEY_RIGHT and self.direction != curses.KEY_LEFT):self.direction = event# 计算蛇的下一个位置next_pos = self.get_next_position()# 检查是否撞墙if next_pos[0] in [0, self.height-1] or \next_pos[1] in [0, self.width-1] or \next_pos in self.snake[1:]:break# 移动蛇self.snake.insert(0, next_pos)# 检查是否吃到食物if next_pos == self.food:self.score += 10self.generate_food()# 加快游戏速度self.speed = max(0.05, self.speed * 0.95)else:self.snake.pop()time.sleep(self.speed)def end_game(self):curses.endwin()print(f"游戏结束!最终得分:{self.score}")def main():try:game = SnakeGame()game.play()game.end_game()except SystemExit as e:curses.endwin()print(e)except Exception as e:curses.endwin()print(f"游戏发生错误:{e}")if __name__ == "__main__":main()

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MQ基础

MQ基础认识MQ结合JAVA客户端 依赖 <!--AMQP依赖,包含RabbitMQ--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency>配置文件 spring:rabbitmq:host: 8.2…

Excel 自动换行后批量设置单元格上下边距

excel 自动换行后 单元格的上下边距挨的很紧,看起来很不舒服 如下图 现在教大家 如何批量设置 单元格中有多行文本后的上下间距,设置成功后 如下图所示:具体步骤: 1、鼠标悬停在 excel 中的任意sheet(页签)上,右键 选择 查看代码 2、在弹出的 Visual Basic 编辑器弹框左…

开发者必备!Github Stars 存储库管理器!

gitstars —— 一个基于 Vite + Vue.js 构建的 GitHub Star 仓库管理器,旨在帮助开发者更好的管理、搜索、查阅收藏的开源项目。大家好,我是 Java陈序员。 Github 作为全球最大的开发者交流平台,拥有数不胜数的开源项目,我们会经常收藏一些开源项目,方便工作和学习。 但随…

1. Linux下 MySQL 的详细安装与使用

1. Linux下 MySQL 的详细安装与使用 @目录1. Linux下 MySQL 的详细安装与使用1. Linux 下安装 MySQL8.0 的详细安装步骤:2. Linxu 当中的MySQL 设置远程登录3. 最后:1. Linux 下安装 MySQL8.0 的详细安装步骤:查看是否安装过MySQL,如果你是用rpm安装, 检查一下RPM PACKAGE:…

临时编辑-----WordPress后台用户手册

登录 WordPress后台默认的登录链接是: https://yourdomain.com/wp-admin/ 输入你的账号(可以是邮箱,也可以是昵称)和密码,即可登录。然后就会进入到你的WordPress网站后台。 注意:忘记你的WordPress密码也不用太慌张,可以从服务器后台进入到WordPress后台。 进来的界面就…

15. Docker容器监控之(CAdvisor+InfluxDB+Granfana)的详细安装和常规使用

15. Docker容器监控之(CAdvisor+InfluxDB+Granfana)的详细安装和常规使用 @目录15. Docker容器监控之(CAdvisor+InfluxDB+Granfana)的详细安装和常规使用1. CAdvisor监控收集+InfluxDB存储数据+Granfana展示图表 的概述1.1 CAdvisor 监控收集1.2 InfluxDB 存储数据1.3 Granfana…

c#中GDI+使用贝塞尔曲线画一朵云

主要是路径的计算 先得到路径if (value.Width > 0 && value.Height > 0) {GraphicsPath.AddBezier(new PointF(RectangleF.Left + RectangleF.Width * 0.1f, RectangleF.Top + RectangleF.Height * 0.55f),new PointF(RectangleF.Left + RectangleF.Width * 0.1f…

如何让你的ida 地址就是RVA

如何让你的ida 地址就是RVA 原理:首先软件进入ida中的时候,其实就相当于把应用程序载入了内存中,RVA其实就是虚拟的便宜地址,也就是在内存中的地址,所以这里的RVA就是在ida中看到的地址-Imagebase Imagebase 其实就是基址。所以我们只需要把imagebase 设置为0即可拿到我…

c#GDI+实现类似油门踏板效果的自定义控件

先看效果图下面是代码protected override void OnPaint(PaintEventArgs e) {e.Graphics.SetGDIHigh();var rect = new Rectangle(0, 0, this.Width, this.Height);// 创建变换矩阵Matrix transformMatrix = new Matrix();// 使用平行四边形的方法近似梯形transformMatrix.Shear…

NocoBase 本周更新汇总:支持全局和批量数据触发自定义操作事件

本周更新包括:支持全局和批量数据触发自定义操作事件,支持数据表预置字段扩展等。汇总一周产品更新日志,最新发布可以前往我们的博客查看。 NocoBase 目前更新包括的版本更新包括三个分支:main ,next和 develop。main :截止目前最稳定的版本,推荐安装此版本。 next:包含…

如何解决远程运维文件传输过程中,面临的安全与效率难题?

堡垒机是一种位于特定网络环境中,用于保障网络和数据安全的设备或系统。它通过集中管理和控制所有远程访问请求,确保每一次操作都经过严格的认证和授权。当用户采用堡垒机开展远程运维和远程访问控制时,需要将安装包、升级包、脚本、工具软件等文件资源,从外部非受控区转移…

20250220

1. 橡胶参考昨晚策略 市场休息 我们也休息。 2. 花生有个多5浪的机会