尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Python游戏开发实战:从零复刻Chrome小恐龙游戏

Python游戏开发实战:从零复刻Chrome小恐龙游戏 1. 项目概述从“Python Dino”说起最近在社区里看到不少朋友在讨论“Python Dino”这个项目乍一听名字你可能会联想到那个经典的Chrome浏览器离线小游戏——那只在沙漠里奔跑、躲避仙人掌和翼龙的小恐龙。没错这个项目的灵感正是来源于此。但“Python Dino”远不止是一个简单的游戏复刻。它本质上是一个以经典游戏为载体的综合性Python编程实践项目其核心价值在于它串联起了从Python环境搭建、基础语法、面向对象编程、图形界面开发到游戏逻辑设计、事件处理乃至性能优化的几乎全链路编程技能。为什么我要专门来聊聊这个项目因为在十多年的编程和教学经历中我发现很多初学者在学完Python语法后会陷入一个迷茫期书本上的例子都懂了但不知道如何把这些零散的知识点组合起来做出一个看得见、摸得着、能运行的东西。“Python Dino”恰好填补了这个空白。它目标明确——做一个能玩的游戏它需求清晰——恐龙要跑、要跳、要躲避障碍它技术栈适中——不需要复杂的3D引擎用Python标准库或轻量级第三方库就能实现。通过完成它你不仅能巩固if-else、for循环、列表、函数这些基础更能亲手实践类与对象的设计、Pygame或Tkinter等GUI库的使用、碰撞检测算法、游戏状态管理乃至简单的多线程处理比如背景音乐。无论你是刚看完《Python编程从入门到实践》想找练手项目的新手还是想重温2D游戏开发乐趣的有经验者这个项目都能给你带来扎实的收获。2. 核心需求与设计思路拆解2.1 游戏核心玩法与功能需求要复现“Dino”游戏我们首先要把它拆解成一个个具体的、可编程实现的功能点。这比直接看代码更重要因为这是软件设计的起点。角色与场景可控角色一只恐龙通常用矩形或简单Sprite图表示它具备两个基本动作奔跑默认状态和跳跃按下空格键或上箭头键触发。障碍物周期性出现的仙人掌低障碍和翼龙高障碍可能需要下蹲躲避。它们从屏幕右侧匀速向左移动。背景一个不断向左滚动的沙漠地面营造出恐龙在向前奔跑的视觉效果。可能还有简单的云朵、远山等装饰性背景元素。记分系统一个不断增长的分数可能随着时间或距离增加碰撞障碍后游戏结束并显示最终分数。核心交互逻辑输入控制监听键盘事件将空格键映射为跳跃命令。跳跃是一个非瞬时的过程涉及上升和下降需要模拟简单的重力加速度。碰撞检测这是游戏逻辑的核心。需要实时判断代表恐龙的矩形或更精确的像素掩码是否与代表障碍物的矩形发生了交集。一旦碰撞发生游戏状态立即切换到“结束”。游戏状态管理至少需要三种状态READY准备等待开始、PLAYING进行中、GAME_OVER结束。不同状态下画面渲染和事件响应的逻辑不同。动态难度为了让游戏可持续玩障碍物出现的速度、频率可以随着分数增加而逐渐提升。2.2 技术选型与架构设计明确了需求接下来就要选择趁手的工具并规划代码结构。这是体现一个程序员设计能力的关键。图形库选择Pygame这是实现此类2D小游戏的首选。它专为游戏开发设计提供了完善的窗口管理、图像渲染、精灵Sprite系统、事件循环、声音播放和矩形碰撞检测等功能。社区资源丰富有大量教程和现成的“Dino”复现代码可以参考。对于本项目Pygame几乎是“开箱即用”的完美选择。Tkinter / PyQt作为GUI库它们也能实现但用于游戏开发略显笨重。你需要手动管理动画帧、重绘和碰撞逻辑相当于重新造轮子。不推荐用于此项目但如果你是为了深入学习某个GUI库将其作为挑战也未尝不可。结论我们选择Pygame。安装简单pip install pygameAPI直观能让我们更专注于游戏逻辑本身。代码架构设计面向对象思想 切忌把所有代码都堆在一个主循环里。良好的架构能让代码清晰、易维护、易扩展。Dinosaur类封装恐龙的所有属性和行为。属性包括位置坐标x, y、速度y_speed用于跳跃、是否在地面、当前帧动画索引等。方法包括jump()触发跳跃、update()根据重力更新位置、draw(screen)在屏幕上绘制自己。Obstacle类或Cactus/Pterodactyl子类封装障碍物。属性包括类型、位置、移动速度、图像等。方法包括update()向左移动、draw(screen)、is_off_screen()判断是否移出屏幕左侧。Game类这是游戏的大脑。它管理游戏状态playing, over持有恐龙实例、障碍物列表、分数、地面滚动位置等。它包含主循环run()在这个循环里依次处理事件、更新所有对象状态、进行碰撞检测、绘制每一帧画面。主程序非常简洁主要是初始化Pygame创建Game实例然后调用game.run()。注意很多初学者教程会省略类的设计用全局变量和函数来完成。虽然也能跑起来但代码会很快变得混乱不堪。坚持使用面向对象的设计是你从“写脚本”迈向“做工程”的重要一步。3. 核心模块实现与关键技术点3.1 环境搭建与Pygame初始化工欲善其事必先利其器。首先确保你的Python环境建议3.8和Pygame就绪。# 在终端或命令提示符中执行 pip install pygame接下来是游戏的初始化代码这相当于搭建舞台import pygame import sys import random # 初始化pygame的所有模块 pygame.init() # 设置游戏窗口尺寸模仿Chrome小游戏的竖屏比例 SCREEN_WIDTH 800 SCREEN_HEIGHT 400 screen pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption(Python Dino - By YourName) # 颜色定义 (R, G, B)方便使用 WHITE (255, 255, 255) BLACK (0, 0, 0) GRAY (240, 240, 240) GROUND_COLOR (83, 83, 83) # 游戏时钟用于控制帧率 clock pygame.time.Clock() FPS 60 # 每秒60帧流畅动画的标准 # 加载字体用于显示分数 font pygame.font.SysFont(None, 36) # None使用系统默认字体关键点解析pygame.init()必须调用它初始化了字体、声音等所有子模块。set_mode()创建了一个“画布”Surface对象我们所有绘制操作都在这上面进行。clock和FPS这是实现平滑动画的灵魂。clock.tick(FPS)会确保主循环每秒最多运行60次从而让游戏在不同性能的电脑上以基本相同的速度运行。没有它游戏速度会和CPU性能直接挂钩快慢不一。3.2 恐龙角色的实现跳跃与重力模拟恐龙的核心是跳跃动作。在现实中跳跃受到重力影响是一个先减速上升后加速下降的过程。我们在游戏中用简单的物理模拟来实现。class Dinosaur: def __init__(self, x50, y300): self.x x # 恐龙左上角的x坐标 self.y y # 恐龙左上角的y坐标注意屏幕坐标系y轴向下为正 self.width 40 self.height 60 self.jump_speed -15 # 初始跳跃速度负值表示向上 self.gravity 0.8 # 重力加速度 self.y_speed 0 # 当前y方向的速度 self.is_jumping False self.on_ground True # 是否站在地面上 # 为了视觉效果可以准备两帧奔跑的图片这里先用矩形代替 self.color (67, 142, 185) def jump(self): 触发跳跃只有在地面上时才能跳 if self.on_ground: self.y_speed self.jump_speed self.is_jumping True self.on_ground False def update(self, ground_y): 更新恐龙位置。ground_y是地面的y坐标 # 应用重力 self.y_speed self.gravity self.y self.y_speed # 检查是否落地 if self.y ground_y - self.height: # 恐龙底部碰到地面 self.y ground_y - self.height # 将其精确放置在地面上 self.y_speed 0 self.is_jumping False self.on_ground True def draw(self, screen): 在屏幕上绘制恐龙这里用矩形代替 pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height)) # 可以在这里画上眼睛让恐龙更生动 eye_x self.x self.width - 10 eye_y self.y 15 pygame.draw.circle(screen, WHITE, (eye_x, eye_y), 5) pygame.draw.circle(screen, BLACK, (eye_x, eye_y), 3)实操心得jump_speed和gravity的数值需要反复调试。-15和0.8的组合能产生一个手感不错的跳跃弧线。你可以尝试调整它们感受不同“星球重力”下的跳跃效果。落地判断if self.y ground_y - self.height:是精确碰撞的基础。这里的ground_y是地面线的y坐标self.height是恐龙的高度。这个计算确保了恐龙“脚”刚好踩在地面上。3.3 障碍物生成与无限循环障碍物是游戏挑战性的来源。我们需要一个管理器来持续、随机地生成它们并在其移出屏幕后回收以节省内存。class Obstacle: def __init__(self, image, x, y, speed): # 在实际项目中image是加载的仙人掌或翼龙图片 # 这里用矩形和颜色区分 self.rect pygame.Rect(x, y, 30, 50) # 假设障碍物宽30高50 self.speed speed self.type random.choice([cactus, cactus, bird]) # 让仙人掌出现概率更高 if self.type bird: self.rect.height 30 # 鸟飞得高碰撞框矮一些 self.color (255, 100, 100) # 红色代表鸟 else: self.color (34, 139, 34) # 绿色代表仙人掌 def update(self): 向左移动 self.rect.x - self.speed def draw(self, screen): pygame.draw.rect(screen, self.color, self.rect) def is_off_screen(self): 判断是否完全移出屏幕左侧 return self.rect.x -self.rect.width class ObstacleManager: def __init__(self, initial_speed5): self.obstacles [] self.speed initial_speed self.timer 0 self.spawn_interval 60 # 初始每60帧约1秒尝试生成一个障碍 def update(self, score): 更新所有障碍物并根据分数调整难度 # 1. 更新现有障碍物位置 for obstacle in self.obstacles[:]: # 使用切片创建副本遍历安全删除 obstacle.update() if obstacle.is_off_screen(): self.obstacles.remove(obstacle) # 2. 生成新障碍物的逻辑 self.timer 1 # 随着分数增加生成间隔缩短速度加快 current_interval max(20, self.spawn_interval - score // 100) # 最小间隔20帧 if self.timer current_interval and random.random() 0.02: # 随机概率生成 # 障碍物从屏幕右侧外生成 obstacle_type random.choice([cactus, cactus, bird]) height 50 if obstacle_type cactus else 30 # 地面y坐标是350障碍物底部应对齐地面 y_pos 350 - height # 鸟可以飞得高一些 if obstacle_type bird: y_pos random.choice([300, 320]) # 两个飞行高度 new_obstacle Obstacle(None, SCREEN_WIDTH, y_pos, self.speed score // 500) self.obstacles.append(new_obstacle) self.timer 0 # 重置计时器 def draw(self, screen): for obstacle in self.obstacles: obstacle.draw(screen) def check_collision(self, dino_rect): 检查恐龙矩形是否与任何障碍物矩形相交 for obstacle in self.obstacles: if dino_rect.colliderect(obstacle.rect): return True return False关键技术对象池思想我们并不真的“删除”和“创建”障碍物而是在列表中移出屏幕外的对象并添加新的对象。在实际更复杂的游戏中会使用真正的对象池来避免频繁的内存分配与回收提升性能。动态难度current_interval max(20, self.spawn_interval - score // 100)这行代码是关键。它让障碍物出现间隔随着分数增加而减少但最小为20帧。self.speed score // 500则让障碍物移动速度越来越快。这两个变量共同构成了游戏的难度曲线。随机性random.random() 0.02和random.choice()为游戏引入了不确定性避免了固定的、可背板的模式让每次游戏体验都略有不同。3.4 碰撞检测游戏逻辑的裁决者碰撞检测的准确性和效率直接影响游戏体验。Pygame提供了非常方便的矩形碰撞检测方法colliderect()。# 在Game类的更新逻辑中 dino_rect pygame.Rect(self.dino.x, self.dino.y, self.dino.width, self.dino.height) if self.obstacle_manager.check_collision(dino_rect): self.game_state “GAME_OVER” # 可以在这里播放一个碰撞音效注意事项矩形碰撞的局限性我们的恐龙和障碍物都是矩形但它们的形状可能并不规则。这会导致“视觉上没碰到但游戏判定碰撞”的情况如下图。这在游戏开发中称为“碰撞框Hitbox”与“视觉框Sprite”不匹配。优化方案使用更小的碰撞框比如把恐龙的碰撞矩形设置得比实际图像小一圈让玩家有少许“容错”空间体验更友好。像素级碰撞检测对于不规则形状Pygame的pygame.sprite.collide_mask()可以基于图像的透明通道进行精确碰撞但计算开销较大不适合大量对象。对于“Dino”这种简单游戏调整矩形大小通常是性价比最高的方案。分层碰撞框对于翼龙鸟可以设置两个矩形一个用于身体一个用于翅膀进行多次检测更精确但更复杂。实操心得在调试碰撞时一个非常有效的方法是在draw方法中额外用pygame.draw.rect(screen, (255,0,0), collision_rect, 2)把碰撞框用红色线条画出来。这样你就能清晰地看到程序“认为”的碰撞区域到底在哪便于快速调整矩形的位置和大小。3.5 地面滚动与视差背景营造动感静止的地面会让奔跑感大打折扣。实现地面滚动的原理很简单准备一张足够宽的地面图片或者重复的图案让它的x坐标不断向左移动当一部分移出屏幕时立刻将其接续到右侧形成无缝循环。class Ground: def __init__(self, y_pos): self.y y_pos self.x1 0 # 第一段地面的x坐标 self.x2 SCREEN_WIDTH # 第二段地面的x坐标紧接在第一段右侧 self.speed 5 # 滚动速度应与障碍物基础速度协调 # 地面可以是一个简单的矩形也可以是一张图片 self.width SCREEN_WIDTH self.height 20 self.color GROUND_COLOR def update(self): 更新两段地面的位置实现循环滚动 self.x1 - self.speed self.x2 - self.speed # 如果某一段地面完全移出屏幕左侧就把它放到右侧接上 if self.x1 -self.width: self.x1 self.x2 self.width if self.x2 -self.width: self.x2 self.x1 self.width def draw(self, screen): pygame.draw.rect(screen, self.color, (self.x1, self.y, self.width, self.height)) pygame.draw.rect(screen, self.color, (self.x2, self.y, self.width, self.height))视差背景进阶为了增加场景深度可以引入多层背景如远处的山、云让它们以比地面更慢的速度滚动。这被称为“视差滚动”。实现原理与地面完全相同只是每层拥有不同的滚动速度speed值更小。离得越远的层速度越慢从而产生立体的运动错觉。这是让2D游戏画面瞬间提升质感的经典技巧。4. 游戏主循环与状态管理一切组件准备就绪后需要用游戏主循环这根线把它们串起来。主循环是游戏的心脏每秒钟跳动数十次由FPS控制每一次跳动都完成“处理输入 - 更新逻辑 - 渲染输出”这个过程。class Game: def __init__(self): self.screen pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) self.clock pygame.time.Clock() self.font pygame.font.SysFont(None, 36) self.reset_game() def reset_game(self): 重置游戏到初始状态 self.dino Dinosaur() self.ground Ground(350) # 地面在y350的位置 self.obstacle_manager ObstacleManager() self.score 0 self.game_state “READY” # READY, PLAYING, GAME_OVER self.game_speed 5 def handle_events(self): 处理所有外部事件键盘、鼠标、退出 for event in pygame.event.get(): if event.type pygame.QUIT: pygame.quit() sys.exit() if event.type pygame.KEYDOWN: if event.key pygame.K_SPACE: if self.game_state “READY”: self.game_state “PLAYING” elif self.game_state “PLAYING”: self.dino.jump() elif self.game_state “GAME_OVER”: # 按空格键重新开始 self.reset_game() self.game_state “PLAYING” def update(self): 更新游戏世界中的所有对象状态 if self.game_state ! “PLAYING”: return # 1. 更新分数例如每帧加1分 self.score 1 # 2. 更新恐龙应用重力检查落地 self.dino.update(self.ground.y) # 3. 更新地面滚动 self.ground.update() # 4. 更新障碍物移动、生成、检测碰撞 self.obstacle_manager.update(self.score) dino_rect pygame.Rect(self.dino.x, self.dino.y, self.dino.width, self.dino.height) if self.obstacle_manager.check_collision(dino_rect): self.game_state “GAME_OVER” def draw(self): 将当前帧绘制到屏幕上 # 1. 清空屏幕用背景色填充 self.screen.fill(WHITE) # 2. 绘制地面 self.ground.draw(self.screen) # 3. 绘制恐龙 self.dino.draw(self.screen) # 4. 绘制障碍物 self.obstacle_manager.draw(self.screen) # 5. 绘制UI分数、状态提示 score_text self.font.render(f‘Score: {self.score}’, True, BLACK) self.screen.blit(score_text, (10, 10)) if self.game_state “READY”: prompt_text self.font.render(‘Press SPACE to START’, True, BLACK) self.screen.blit(prompt_text, (SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT // 2)) elif self.game_state “GAME_OVER”: game_over_text self.font.render(‘GAME OVER’, True, (255, 50, 50)) restart_text self.font.render(‘Press SPACE to RESTART’, True, BLACK) self.screen.blit(game_over_text, (SCREEN_WIDTH // 2 - 70, SCREEN_HEIGHT // 2 - 30)) self.screen.blit(restart_text, (SCREEN_WIDTH // 2 - 120, SCREEN_HEIGHT // 2 10)) final_score_text self.font.render(f‘Final Score: {self.score}’, True, BLACK) self.screen.blit(final_score_text, (SCREEN_WIDTH // 2 - 80, SCREEN_HEIGHT // 2 50)) # 6. 将绘制好的内容更新到显示器 pygame.display.flip() def run(self): 游戏主循环 running True while running: self.handle_events() # 处理输入 self.update() # 更新逻辑 self.draw() # 渲染画面 self.clock.tick(FPS) # 控制帧率 if __name__ “__main__”: game Game() game.run()主循环的精髓handle_events-update-draw-clock.tick(FPS)这个顺序是游戏编程的黄金法则。它保证了输入响应的及时性、世界状态更新的同步性以及画面渲染的稳定性。clock.tick(FPS)是维持游戏节奏不飘忽的关键。5. 性能优化与常见问题排查即使是这样一个小游戏在开发过程中也会遇到各种性能或逻辑问题。这里记录一些典型的“坑”和解决方案。5.1 性能优化技巧图像加载与重用问题如果在每一帧的draw方法里都加载图像会引发巨大的磁盘I/O和内存开销导致游戏卡顿。解决所有图像资源恐龙精灵图、障碍物图片、背景都应在游戏初始化时__init__中一次性加载好并存储在变量中。draw方法只进行blit位块传输操作这是非常高效的。def __init__(self): self.dino_image pygame.image.load(‘dino.png’).convert_alpha() # 加载并转换格式提升blit速度 self.cactus_image pygame.image.load(‘cactus.png’).convert_alpha()脏矩形更新问题pygame.display.flip()或pygame.display.update()默认会更新整个屏幕。对于只有局部变化的画面比如恐龙跳跃、障碍物移动这是不必要的性能浪费。解决使用“脏矩形”技术。只记录发生变化的屏幕区域矩形列表然后只更新这些区域。# 在update方法中记录需要重绘的区域 dirty_rects [] dirty_rects.append(self.dino.get_rect()) # 恐龙上一帧的位置 dirty_rects.append(self.dino.get_rect()) # 恐龙当前帧的位置可能相同 # ... 记录所有移动对象的旧位置和新位置 # 在draw方法最后 pygame.display.update(dirty_rects) # 只更新脏矩形区域注意对于“Dino”这种全屏元素都在动的游戏脏矩形优化效果有限甚至可能因为计算矩形而增加开销。但对于UI复杂、大部分区域静态的游戏这是必备优化。对象管理及时从障碍物列表中移除已经移出屏幕的物体防止列表无限膨胀导致遍历和碰撞检测变慢。5.2 常见问题与排查实录问题现象可能原因排查与解决方案游戏运行速度极快或极慢没有使用clock.tick(FPS)控制帧率。在主循环末尾确保调用了self.clock.tick(60)。恐龙跳跃“粘滞”或反应迟钝1. 事件处理代码放错了位置比如放在了update之后。2. 键盘事件采样率问题。1. 确保handle_events在update和draw之前调用。2. 除了KEYDOWN事件还可以结合pygame.key.get_pressed()来检测持续按下的键让跳跃响应更跟手。碰撞检测不准确太松或太紧碰撞矩形的大小或位置设置不合理。使用pygame.draw.rect将碰撞框可视化出来直观地调整矩形的x, y, width, height。障碍物生成过于密集或稀疏spawn_interval和随机生成概率(random.random() 0.02)设置不当。调整这两个参数。可以添加一个调试模式在屏幕上打印当前生成间隔和障碍物数量。游戏越玩越卡1. 障碍物对象只增不减内存泄漏。2. 每一帧都在创建新的font.render对象。1. 确保is_off_screen()的障碍物被从列表中移除。2. 对于不变的文本如“GAME OVER”可以预先渲染好Surface并保存而不是每帧重新渲染。画面闪烁在绘制过程中多次调用pygame.display.flip()。确保一帧内所有绘制完成后再调用一次flip()或update()。一个实用的调试技巧在游戏窗口标题栏显示实时帧率FPS和游戏状态变量。# 在Game类的draw方法末尾或主循环中 fps int(self.clock.get_fps()) pygame.display.set_caption(f“Python Dino - FPS: {fps} | Score: {self.score} | State: {self.game_state}”)这样你就能实时监控游戏性能快速定位是哪个逻辑环节导致了帧率下降。6. 从原型到产品美化与功能扩展一个只有色块的游戏是缺乏吸引力的。让我们为“Python Dino”穿上外衣并添加一些让它更完整的特性。6.1 资源加载与精灵动画准备素材从网上寻找或自己绘制一套简单的精灵图Sprite Sheet。例如一张包含恐龙奔跑2-3帧的图片一张包含不同仙人掌和翼龙的图片。加载与裁剪# 加载精灵图 sprite_sheet pygame.image.load(‘dino_sprites.png’).convert_alpha() # 假设每帧宽44px高47px self.run_frames [ sprite_sheet.subsurface((0, 0, 44, 47)), sprite_sheet.subsurface((44, 0, 44, 47)) ] self.current_frame 0 self.animation_speed 0.2 # 控制动画播放速度 self.frame_counter 0动画更新在恐龙的update方法中根据是否在地面来更新帧索引。def update(self, ground_y): # ... 原有的位置更新逻辑 ... # 动画更新 if self.on_ground: # 只有在地上跑时才切换帧 self.frame_counter self.animation_speed if self.frame_counter len(self.run_frames): self.frame_counter 0 self.current_frame int(self.frame_counter) # 跳跃时可以使用一个固定的跳跃帧图片绘制精灵在draw方法中不再画矩形而是绘制对应的帧。def draw(self, screen): current_image self.jump_image if self.is_jumping else self.run_frames[self.current_frame] screen.blit(current_image, (self.x, self.y))6.2 音效与背景音乐声音是游戏体验的一半。Pygame的mixer模块让添加声音变得简单。# 初始化音效通常在游戏初始化时放在pygame.init()之后 pygame.mixer.init() # 加载音效文件 jump_sound pygame.mixer.Sound(‘jump.wav’) crash_sound pygame.mixer.Sound(‘crash.wav’) # 加载背景音乐 pygame.mixer.music.load(‘bg_music.mp3’) pygame.mixer.music.set_volume(0.5) # 设置音量 pygame.mixer.music.play(-1) # -1表示循环播放 # 在恐龙跳跃时播放音效 def jump(self): if self.on_ground: # ... 跳跃逻辑 ... jump_sound.play() # 在游戏结束时播放碰撞音效 if self.obstacle_manager.check_collision(dino_rect): self.game_state “GAME_OVER” crash_sound.play() pygame.mixer.music.stop()6.3 功能扩展思路一个基础版本完成后你可以尝试以下扩展让项目成为你简历上的亮点增加下蹲动作监听下箭头键让恐龙可以蹲下躲避飞行的翼龙。这需要为恐龙增加一个“蹲下”状态和对应的碰撞框更矮更宽。实现“无敌”或“冲刺”道具随机生成一个特殊的障碍物比如星星恐龙碰到后一段时间内无视碰撞或速度加快。本地高分记录使用json或sqlite3模块将最高分保存在本地文件中每次游戏结束后比较并更新。增加昼夜交替通过一个计时器周期性改变背景和地面的颜色模拟从白天到夜晚的变化。打包成可执行文件使用PyInstaller或cx_Freeze将你的游戏打包成.exe文件分享给没有安装Python的朋友。pip install pyinstaller pyinstaller --onefile --windowed --name “PythonDino” your_game.py开发“Python Dino”的整个过程就是一个典型的软件项目生命周期需求分析、技术选型、架构设计、模块实现、测试调试、优化扩展。它麻雀虽小五脏俱全。当你完整地走完这一遍你所收获的绝不仅仅是一个小游戏而是如何用Python这门语言从零开始构建一个可交互、有逻辑、有状态的应用程序的完整思维模式和实战能力。这远比单纯学习语法更有价值。
返回列表