十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Pygame 弹球模拟器(Bouncing Ball Simulator):基于重力与弹性碰撞的物理仿真入门实战

Pygame 弹球模拟器(Bouncing Ball Simulator):基于重力与弹性碰撞的物理仿真入门实战 示例工程【免费下载链接】python-mini-projectsA collection of simple python mini projects to enhance your python skills项目地址https://gitcode.com/gh_mirrors/py/python-mini-projects点击查看免费下载python-mini-projects仓库中的projects/Bouncing_ball_simulator是一个用 Pygame 实现的轻量级物理仿真示例5 个小球在一个 800×600 的容器内受重力加速下落并与容器底部、左右墙壁及顶部发生弹性碰撞后持续反弹。本文以该项目的 README.md 为主线结合 ball_bounce.py 源码逐行拆解其物理模型、碰撞检测逻辑与主循环结构帮助你快速掌握用 Pygame 编写重力 弹性碰撞仿真程序的核心套路并了解如何调整参数获得不同的弹跳效果。项目概览容器内的重力弹跳仿真项目描述来自 README.md指出该脚本展示的是若干小球在重力作用下于一个容器内弹跳的仿真过程小球不仅受重力影响还会与容器的底部和侧壁发生碰撞。在 ball_bounce.py 的源码注释中作者进一步说明程序模拟了5 个球在重力加速度作用下的弹跳伴随与容器墙壁的弹性碰撞elastic collision作者将其定位为一个看起来很有趣的可视化演示。从源码结构看整个程序只有一个类ball和一个主循环没有引入复杂框架非常适合作为 Pygame 入门或物理仿真入门的教学示例。项目全部资源文件如下文件作用ball_bounce.py主程序仿真逻辑、碰撞检测、渲染循环background-img.jpg容器背景图1000×666 纯色背景ball.png小球图像资源32×32requirements.txt依赖声明pygame2.0.2运行环境与依赖准备根据 README.md 的 Prerequisites 部分运行本项目需要满足两个前提Python 3脚本基于 Python 3 编写pygame 模块。依赖版本在 requirements.txt 中固定为pygame2.0.2安装依赖的推荐方式是按 README 给出的命令直接通过 requirements 文件安装pip3 install -r requirements.txt提示pip3用于明确指向 Python 3 的包管理器如果你使用虚拟环境或python3 -m pip效果等价。固定版本pygame2.0.2能保证渲染接口行为一致避免因 pygame 2.x 不同小版本的 API 差异导致运行异常。快速运行一条命令启动仿真README 的 How to run the script 部分给出了标准运行流程进入源码所在目录projects/Bouncing_ball_simulator/打开终端执行python3 ball_bounce.py运行后会出现标题为Ball Bounce Simulation的 800×600 Pygame 窗口背景为background-img.jpg5 个橙色小球ball.png从随机位置开始运动在重力作用下下落、与容器壁碰撞并持续弹跳直到你关闭窗口触发pygame.QUIT事件为止。需要注意程序通过相对路径加载图像资源pygame.image.load(background-img.jpg)与pygame.image.load(ball.png)因此必须保持在projects/Bouncing_ball_simulator/目录下运行否则会因找不到图片文件而报错。源码级解析物理模型与碰撞检测4.1 窗口初始化与资源加载import pygame, time, random pygame.init() screen pygame.display.set_mode((800, 600)) background pygame.image.load(background-img.jpg) pygame.display.set_caption(Ball Bounce Simulation)pygame.init()初始化所有 pygame 模块set_mode((800, 600))创建 800×600 像素的仿真容器窗口load(background-img.jpg)加载容器背景图主循环中每帧通过screen.blit(background, (0, 0))重绘set_caption设置窗口标题。4.2ball类属性设计与物理常量class ball: ball_image pygame.image.load(ball.png) g 1 def __init__(self): self.velocityX 4 self.velocityY 4 self.X random.randint(0, 768) self.Y random.randint(0, 350)类属性与实例属性的职责划分属性类型值/取值范围含义ball_image类属性ball.png所有小球共享同一张图像资源g类属性1每帧施加的重力加速度像素/帧²velocityX实例属性初始4水平方向速度像素/帧velocityY实例属性初始4垂直方向速度像素/帧向下为正X实例属性随机0~768水平坐标像素Y实例属性随机0~350垂直坐标像素两个值得注意的细节初始位置随机化X在0~768随机Y在0~350随机。768 800 - 32、350均考虑了小球图像尺寸32×32与窗口尺寸确保小球出生时大致处于容器上半部分且不越出左右边界。重力常数作为类属性g被定义为类属性而非实例属性从设计意图看它代表作用于所有小球的统一重力场无需为每个球单独存储。4.3move_ball()逐帧物理更新与碰撞响应def move_ball(self): # 重力每帧给垂直速度叠加向下的加速度 self.velocityY ball.g # 按速度更新位置 self.X self.velocityX self.Y self.velocityY # 左右墙壁碰撞水平速度取反 if self.X 0 or self.X 768: self.velocityX * -1 # 顶部碰撞仅在向上运动时取反并夹紧 if self.Y 0 and self.velocityY 0: self.velocityY * -1 self.Y 0 # 底部碰撞仅在向下运动时取反并夹紧 if self.Y 568 and self.velocityY 0: self.velocityY * -1 self.Y 568这段代码是仿真的核心本质上是离散时间步的欧拉积分每帧一小步重力积分velocityY ball.g每帧垂直速度增加 1 个像素/帧模拟重力持续加速下落位移更新X velocityX; Y velocityY用当前速度更新位置左右墙壁碰撞当X 0或X 768即小球越出左右边界768 800 - 32考虑球宽时velocityX * -1使水平速度反向——这就是弹性碰撞在代码中的体现速度大小不变、方向反转顶部碰撞当Y 0且仍在向上运动velocityY 0时垂直速度取反并将位置夹紧到Y 0避免小球穿出顶部底部碰撞当Y 568568 600 - 32考虑球高且仍在向下运动velocityY 0时速度取反并夹紧到Y 568小球落在容器底部后反弹。碰撞条件中带方向判断velocityY 0/velocityY 0是避免边界抖动的关键只有球正在朝边界运动时才触发反弹防止球处于边界且已反向运动时被重复取反、卡在边界附近来回振荡。这是 2D 边界碰撞处理中值得借鉴的实践。4.4 渲染与主循环def render_ball(self): screen.blit(ball.ball_image, (self.X, self.Y)) Ball_List [ball(), ball(), ball(), ball(), ball()] running True while running: for event in pygame.event.get(): if event.type pygame.QUIT: running False time.sleep(0.02) screen.blit(background, (0, 0)) for ball_item in Ball_List: ball_item.render_ball() ball_item.move_ball() pygame.display.update()主循环的固定节奏为事件处理轮询pygame.event.get()收到pygame.QUIT点击窗口关闭按钮时退出循环帧率控制time.sleep(0.02)每帧间隔约 20ms对应约 50 FPS 的刷新节奏同时也决定了物理仿真的时间步长清屏重绘先blit背景图覆盖上一帧画面再遍历Ball_List依次渲染并更新每个小球画面提交pygame.display.update()将绘制结果显示到窗口。Ball_List一次创建 5 个ball()实例因此5 个球的数量就由这行列表字面量决定——想增加或减少小球数量直接增删这里的元素即可。参数调优改变弹跳效果的关键旋钮所有物理行为都由少量常量控制调整它们即可获得截然不同的观感参数位置调整方向效果ball.g类属性调大 → 下落更快、弹跳更急促调小 → 失重感、漂浮感控制重力强度velocityX/velocityY__init__调大 → 运动更激烈设为 0 → 只做垂直弹跳控制初始发射速度time.sleep(0.02)主循环调小 → 仿真更快调大 → 慢动作回放控制帧率与时间步长set_mode((800, 600))初始化改变容器尺寸时需同步调整边界常量768、568容器大小Ball_List元素个数主循环前增删ball()实例同时弹跳的小球数量例如若将窗口改为(1024, 768)则左右边界应相应改为1024 - 32 992、底部边界改为768 - 32 736同时建议同步调整Y的随机上限。从源码结构看可扩展方向当前实现是重力 墙壁弹性碰撞的最小可用版本从源码结构看以下扩展点都有清晰的落点小球之间的碰撞目前move_ball()只处理球与容器的碰撞Ball_List中各球彼此穿透。可在主循环中增加两两距离检测当球心距离小于直径时交换/反转速度分量能量损耗非完全弹性将velocityY * -1改为velocityY * -0.9恢复系数 1即可模拟每次反弹损失能量的阻尼效果小球最终会静止在底部随机化初始速度__init__中的velocityX/velocityY目前固定为 4可改为random.randint(...)让每次运行的运动轨迹都不同交互控制在事件循环中监听键盘/鼠标事件动态调整ball.g或增加新球。小结Bouncing_ball_simulator用不到 60 行代码完整演示了 Pygame 物理仿真的标准骨架初始化窗口 → 加载资源 → 定义运动对象速度积分 边界碰撞 → 主循环事件、更新、渲染。其重力积分、带方向判断的边界碰撞、以及用类属性统一管理物理常量的设计都是可复用到其他 2D 仿真项目如弹幕、粒子系统、平台跳跃游戏的基础模式。按 README.md 的指引安装依赖并运行 ball_bounce.py再结合本文的参数调优表动手修改几个常量就能直观感受到每个参数对弹跳效果的影响。赞分享示例工程【免费下载链接】python-mini-projectsA collection of simple python mini projects to enhance your python skills项目地址https://gitcode.com/gh_mirrors/py/python-mini-projects点击查看免费下载相关推荐Dify工作流图片显示排障手册3条路径一次搞定Dify工作流图片显示排障手册3条路径一次搞定 跑完一个 Dify 工作流回复里本该出现图片的位置只剩一个灰色叉或者图表节点明明执行成功前端却显示一行示例工程Bubblezone实战教程手把手教你实现终端列表项的点击交互效果Bubblezone实战教程手把手教你实现终端列表项的点击交互效果 Bubblezone是一款专为BubbleTea打造的实用工具能够轻松实现终端应用中的鼠如何将 Sublime Text 3 快速升级为完整 Python IDEAnaconda 终极指南如何将 Sublime Text 3 快速升级为完整 Python IDEAnaconda 终极指南 Anaconda 是一个强大的 Sublime Text人工智能大模型计算机视觉OCR本地部署AI 技能上一篇突破浏览器性能瓶颈transformers.js中卷积网络(CNN)的WebGPU加速实现下一篇SkyReels-V2 无限长视频生成从零跑通第一条长视频的新手教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表