ARTICLE DETAIL

资讯详情

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

Python复刻Chrome小恐龙快跑:pygame游戏开发实战

Python复刻Chrome小恐龙快跑:pygame游戏开发实战 简介一份用Python实现的经典小恐龙快跑小游戏源码仿照谷歌浏览器内恐龙跑酷玩法为Python入门者和游戏开发爱好者提供轻量级练手项目。压缩包共两个文件均为py脚本体积仅2KB其中Game7.py是主程序涵盖游戏初始化、主循环、事件响应、碰撞判定和得分累加cfg.py作为配置文件集中管理屏幕分辨率、背景颜色、角色属性与移动速度便于修改参数。已有1595人学习下载。通读源码可以理解pygame等二维游戏库的基础用法看到类与对象、模块导入、条件语句和循环在真实项目中的配合也能掌握恐龙跳跃、障碍物生成、碰撞检测与得分刷新的实现思路。借助cfg.py还能继续扩展多级关卡、添加跳跃或撞击音效、制作逐帧动画并完善开始菜单和暂停界面是一份麻雀虽小但结构清晰的入门参考。 你打开Chrome碰到断网的时候十有八九会看到一只像素小恐龙。它蹲在荒漠里紧凑的跑步动作配上跳跃、下蹲游戏虽小却把横版跑酷的核心机制都做全了。我休假时用Python把这只“小恐龙快跑”从零复刻了一遍源码现在还有一堆版本存在硬盘里。之所以做这件事是因为这个游戏体量合适——比“贪吃蛇”有内容比“飞机大战”更容易理解非常适合当作pygame入门后的第一个完整项目。这篇文章以我当时整理的Python小恐龙快跑小游戏源代码为线索把项目设计、模块实现、运行调试和经验教训一次讲清楚项目中用到的主要是pygame库语法全是最基础的类、循环、事件和碰撞判断如果你已经学完了Python基本语法可以直接照着抄作业。1. 项目整体设计与技术选型1.1 游戏机制拆解Chrome恐龙游戏看起来简单实际拆开之后里面全是横版跑酷动作游戏的标准零件。玩家控制一只小恐龙在一张不断向后滚动的沙漠地图上奔跑需要跳过尺寸不一的仙人掌障碍躲避天上偶尔出现的飞鸟。地面是固定的恐龙只能做两件事跳跃和下落。游戏没有终点分数随时间增长速度会逐步提升障碍物出现频率跟着变高直到玩家撞上障碍物导致Game Over。用模块化的眼光看这个小游戏能分成4个核心系统。一个是角色系统负责恐龙的起跳、重力下落、落地检测和跑步动画。一个是障碍物系统负责仙人掌/飞鸟的生成、向左移动、离屏回收。一个是碰撞系统核心就是矩形相交判定判断恐龙和障碍物的包围盒是不是重叠。还有一个是计分与状态系统包括分数累加、速度递增、游戏结束与重新开始。把这4个系统分开写代码清晰度会很高出Bug也好定位这比一开始就把所有代码堆在一个循环里要舒服得多。1.2 为什么选择Python加pygame选Python不是因为它适合做游戏而是因为它适合“学游戏”。C配Unity、C#配Godot当然是正经游戏开发路线但对一个刚入门的Python学习者来说工具链太重还没碰到游戏逻辑就先被引擎门槛劝退了。pygame的优势一句话就能说清楚所有游戏概念都能用最小代码量落地。比如窗口创建用pygame只需要两行代码。你要画的恐龙、仙人掌可以直接用矩形、圆形、多边形画出来不需要准备美术素材。键盘监听、时钟控制、图像加载这些基础功能pygame都封装得足够简单网上资料也多到查不完。这套方案的缺点是性能上限不高不适合做复杂3D或大型2D游戏但小恐龙快跑这种2D休闲单机游戏pygame完全够用。我实际跑下来60帧全程稳定CPU占用也低验证一个游戏机制绰绰有余。1.3 代码结构规划我在动手写之前先定了目录结构避免代码全挤在一个文件里后期难受。dino_game/ ├── main.py # 游戏入口与主循环 ├── dino.py # 恐龙类 ├── obstacle.py # 障碍物类 ├── game.py # 游戏状态管理与碰撞检测 └── background.py # 地面与背景移动小项目不用过度设计但把类分开放是值得的。就算你最后把所有内容写进一个main.py脑子里也最好有这层结构后面加功能、改参数都好办。2. 核心代码模块逐步拆解2.1 游戏窗口与主循环窗口大小我参考了原版比例定为800x300地面放在纵坐标250的位置。import pygame import random pygame.init() WIDTH, HEIGHT 800, 300 GROUND_Y 250 FPS 60 WIN pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption(Python小恐龙快跑) clock pygame.time.Clock()主循环是所有游戏的心跳每帧做四件事处理输入事件、更新所有对象的位置、检测碰撞、重绘画面。running True while running: clock.tick(FPS) for event in pygame.event.get(): if event.type pygame.QUIT: running False if event.type pygame.KEYDOWN and event.key pygame.K_SPACE: dino.jump() dino.update() for obstacle in obstacles: obstacle.update() obstacles [obs for obs in obstacles if not obs.off_screen()] if check_collision(dino, obstacles): running False WIN.fill((255, 255, 255)) dino.draw(WIN) for obstacle in obstacles: obstacle.draw(WIN) pygame.display.update()这个循环本身没有技术难度真正考验逻辑的是每一帧里各个对象的状态更新顺序。我一开始把碰撞检测放在了对象更新之前结果恐龙明明已经跳起来还是被判碰上了仙人掌后来调整了顺序才正常。2.2 恐龙类的跳跃与动画恐龙核心行为是“跳跃—下落—落地”。我给它设置了重力常量和跳跃初速度。class Dino: GRAVITY 0.6 JUMP_VELOCITY -13 def __init__(self, x, y): self.x x self.y y self.vel_y 0 self.width 44 self.height 47 self.is_jumping False self.run_frame 0 def jump(self): if not self.is_jumping: self.is_jumping True self.vel_y self.JUMP_VELOCITY def update(self): if self.is_jumping: self.vel_y self.GRAVITY self.y self.vel_y if self.y GROUND_Y - self.height: self.y GROUND_Y - self.height self.is_jumping False self.vel_y 0 else: self.run_frame 1 def draw(self, win): color (83, 83, 83) pygame.draw.rect(win, color, (self.x, self.y, self.width, self.height))跳跃手感的关键是重力和初速度两个参数。原版恐龙起跳干脆、下落有力。GRAVITY0.6、JUMP_VELOCITY-13是我调了好几轮的效果起跳大约能跳到4个恐龙身位的高度落地不拖泥带水。如果你觉得跳跃太飘就按0.1的步长加重力如果觉得跳得太矮就把初速度绝对值加大1到2。恐龙跑步动画我这里用矩形做了简化颜色统一是深灰色。如果想做双帧跑步效果可以准备两张恐龙位图或自己画两帧跑动姿势在run_frame里轮流切换索引就行。2.3 障碍物的生成与移动障碍物有两种形态地面仙人掌和空中飞鸟。class Obstacle: SPEED 6 def __init__(self, x, y, width, height): self.x x self.y y self.width width self.height height self.kind cactus def update(self): self.x - Obstacle.SPEED def off_screen(self): return self.x self.width 0 def draw(self, win): if self.kind cactus: color (60, 120, 80) else: color (120, 80, 60) pygame.draw.rect(win, color, (self.x, self.y, self.width, self.height))生成逻辑不要每帧都随机做否则会有连续几个障碍扎堆挤压人物的运气局。我用的是一个冷却计时器每隔一段时间才随机生成一次间隔在80到150帧之间浮动。spawn_timer 0 if spawn_timer 0: obs Obstacle(WIDTH, random.randrange(GROUND_Y - 80, GROUND_Y - 20), random.choice([20, 30, 40]), random.choice([35, 50, 65])) obstacles.append(obs) spawn_timer random.randint(60, 130) else: spawn_timer - 1生成高度用GROUND_Y偏移来控制仙人掌在地面飞鸟则生成在离地面20到80像素的半空。2.4 碰撞检测与计分加速碰撞检测我用了最简单的矩形相交判定这是2D小游戏的默认方案。def check_collision(dino, obstacle): if dino.x dino.width obstacle.x and dino.x obstacle.x obstacle.width: if dino.y dino.height obstacle.y: return True return False这个方式精度不高恐龙轮廓边缘和矩形实际边缘有偏差视觉上会显得“已经闪开了却还是死了”。改进方向有两条一是把碰撞矩形按实际外形缩小一圈比如恐龙矩形向内收缩4像素仙人掌收缩3像素二是用像素级碰撞检测需要逐像素比较两张图片的alpha通道性能开销大不少只有做美术程度较高的游戏时才有必要。计分我用帧数代替时间每帧加1分同时每500分提升一次障碍物速度。score 1 if score % 500 0: Obstacle.SPEED 1这个设计让游戏后期越来越紧张和原版的难度曲线一致。3. 从零复现完整项目搭建过程3.1 环境准备与依赖安装先在本地装好Python 3.10以上版本。打开命令行窗口检查环境python --version然后安装pygamepip install pygame国内网络如果下载慢可以用清华镜像源加速pip install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple装完进入Python交互环境试一下import pygame print(pygame.version.ver)能打印出版本号就说明环境没问题。这一步卡住的人多半是Python没有加入PATH环境变量或者是机器上同时装了多个Python版本导致pip装到了别的解释器上。3.2 素材方案与画面实现我不建议一上来就去找像素素材自己画更容易控制效果和版权。小恐龙原版是像素风但我们做学习项目时可以用简单的几何图形代替恐龙用灰色矩形加两个腿部方块仙人掌用绿色矩形组合飞鸟用棕色圆形加翅膀。如果你坚持用图片pygame读取图片的方式是dino_image pygame.image.load(dino.png) win.blit(dino_image, (x, y))注意图片背景要处理成透明PNG否则会出现白色方块违和感立刻拉满。3.3 完整代码串联与运行我把main.py主循环的完整逻辑补全整个游戏就能跑了。def main(): dino Dino(80, GROUND_Y - 47) obstacles [] score 0 spawn_timer 0 running True while running: clock.tick(FPS) for event in pygame.event.get(): if event.type pygame.QUIT: running False if event.type pygame.KEYDOWN: if event.key pygame.K_SPACE: dino.jump() dino.update() if spawn_timer 0: obs Obstacle(WIDTH, random.randrange(GROUND_Y - 80, GROUND_Y - 20), random.choice([20, 30, 40]), random.choice([35, 50, 65])) obstacles.append(obs) spawn_timer random.randint(60, 130) else: spawn_timer - 1 for obs in obstacles: obs.update() obstacles [obs for obs in obstacles if not obs.off_screen()] for obs in obstacles: if check_collision(dino, obs): running False print(Game Over! Score:, score) break score 1 if score % 500 0: Obstacle.SPEED 1 WIN.fill((255, 255, 255)) dino.draw(WIN) for obs in obstacles: obs.draw(WIN) pygame.display.update() pygame.quit()运行方式python main.py按下空格键起跳游戏开始。撞上仙人掌后控制台输出最终分数。这里我故意没有做“点击重新开始”的复杂界面目的就是先把核心循环跑通把注意力放在游戏机制上。4. 常见踩坑与调试心得4.1 跳跃手感很飘这是新手的重灾区。原因一般是重力加速度设置得太小导致恐龙起跳后在空中停留时间过长。原版小恐龙跳跃总时长大概是半秒多一点点你可以在调试时自己感受如果跳跃期间时间明显超过1秒说明重力太小。调节顺序我建议这样先固定初速度为-13然后每次把重力调大或调小0.1反复跑几局找手感和节奏。别一次调0.5步子太大容易直接飞出屏幕。4.2 碰撞判定过于严格用矩形判定时如果恐龙和仙人掌的包围盒贴合角色外形边缘会有明显的“误伤”。比如恐龙张嘴的那一格其实没有碰到仙人掌但矩形已经重叠了。解决办法是给碰撞区域留出安全边距我常用的收缩值在3到6像素之间。# 在碰撞检测时对dino和obstacle都做内缩 dino_box (dino.x 4, dino.y 4, dino.width - 8, dino.height - 6) obs_box (obs.x 3, obs.y 3, obs.width - 6, obs.height - 3)这样视觉上更接近真实接触点容错率也更高玩家体验会明显改善。4.3 不同电脑上速度不一样clock.tick(FPS)保证了游戏逻辑帧率一致但如果你没有做任何帧率控制游戏速度会直接取决于电脑性能。在高刷新率显示器上跑得飞快在低帧率电脑上又慢得像蜗牛。统一用clock.tick(60)约束循环并让所有速度参数基于“每帧”计算就能保证跨设备表现一致。4.4 障碍物扎堆生成随机数没有加冷却会导致连续3个仙人掌同时出现在屏幕上玩家根本无处躲避。处理方案就是我前面提过的“spawn_timer冷却机制”设置60到130帧的随机生成间隔。如果追求更高品质可以再做障碍物最小间距检测生成前检查已有障碍物的x坐标保证间距不小于某个值。4.5 素材版权提醒如果你从网上下载了Chrome恐龙原版图片或音效建议仅用于本地学习不要拿去发布或打印销售。原版素材版权属于其开发方。自己用代码画几何图形或者使用CC0协议的开源素材都没有版权隐患。这也是我这次坚持用pygame.draw.rect画所有角色的原因。最后再分享一个我个人很受益的小习惯每一次改动无论多小都先跑一次游戏验证手感再提交一个版本。我现在电脑里还留着V1到V7共7个版本的代码V1只实现了“恐龙原地跳跃”V7才有了完整的加速和得分逻辑。回头看这些版本记录的不只是代码变化更是对游戏机制一点点加深理解的过程。这个项目如果你还有精力后续可以试试加入音效、双人模式、体型更大的Boss障碍物或者把帧绘制改成图片素材做成完整的质感项目。所有扩展的核心其实都没跳出这篇文章讲的这套主循环和碰撞逻辑。本文还有配套的精品资源点击获取
返回列表