用Python玩转《The Nature of Code》 实现物理世界 新手也能轻松上手

内容分享3周前发布
0 1 0

你是否曾好奇:游戏里角色的跳跃轨迹、飘落的雨滴、飘动的树叶,这些“拟真效果”是怎么用代码实现的?实则答案就藏在一本经典书里——《The Nature of Code》(《代码本色》)。

这本书的核心是用代码还原物理规律,列如重力、弹力、碰撞,原本用Processing语言编写,今天我带你用更熟悉的Python“复刻”,从最基础的“粒子下落”开始,零基础也能跟着做,最后还能生成动态效果,学会就能用在可视化、小游戏开发里!

用Python玩转《The Nature of Code》 实现物理世界 新手也能轻松上手

一、为什么用Python学《The Nature of Code》?新手也能踩稳的3个理由

许多人看到“物理”“代码”就怕,但用Python学《The Nature of Code》,门槛真的很低:

1. 库够简单,不用造轮子:我们用pygame(处理图形和动画)和math(基础计算),这两个库安装简单,API直观,列如画个圆、让物体动起来,几行代码就搞定,不用自己写复杂的图形渲染逻辑。

2. 物理知识“碎片化”学:不用啃完高中物理,书中每个案例只对应一个小规律,列如“粒子下落”只需要理解“重力是恒定加速度”,跟着代码走,边写边理解,比死记公式快10倍。

3. 效果可视化,成就感拉满:写完代码就能看到动态效果——列如粒子从屏幕上方落下,碰到地面弹起,这种“即时反馈”会让你越学越有劲儿,不像学单纯的语法那样枯燥。

先别急着写代码,我们先把环境搭好,5分钟就能搞定。

用Python玩转《The Nature of Code》 实现物理世界 新手也能轻松上手

二、3步搭好环境!新手也不会错的操作指南

第一步:安装Python(已有可跳过)

去Python官网(www.python.org)下载最新版,安装时记得勾选“Add Python to PATH”,这样后续在命令行里就能直接调用Python。

第二步:安装必备库

打开电脑的“命令提示符”(Windows)或“终端”(Mac),输入两行命令,按回车等待安装完成:

pip install pygame

# (math是Python自带库,不用额外安装)

如果出现“pip不是内部命令”,大致率是安装Python时没勾“Add to PATH”,重新安装时勾选即可。

第三步:验证环境

新建一个Python文件(列如叫test.py),输入以下代码:

import pygame

import math

# 初始化pygame

pygame.init()

# 创建窗口

screen = pygame.display.set_mode((800, 600))

# 设置窗口标题


pygame.display.set_caption(“《代码本色》Python测试”)

# 主循环

running = True

while running:

# 处理退出事件

for event in pygame.event.get():

if event.type == pygame.QUIT:

running = False

# 填充背景色(浅灰色)

screen.fill((240, 240, 240))

# 画一个红色的圆(模拟粒子)

pygame.draw.circle(screen, (255, 0, 0), (400, 300), 20)

# 更新屏幕

pygame.display.flip()

# 退出pygame

pygame.quit()

双击运行这个文件,如果弹出一个浅灰色窗口,中间有个红色圆,说明环境没问题!接下来,我们正式进入第一个案例——“粒子下落”,还原《The Nature of Code》里最经典的物理效果。

用Python玩转《The Nature of Code》 实现物理世界 新手也能轻松上手

三、实战案例:100行代码实现“粒子下落+地面反弹”,吃透“重力”和“弹力”

《The Nature of Code》第一章的核心是“粒子系统”,我们先做一个最简单的粒子:让它从屏幕上方落下,碰到地面后弹起(模拟重力和弹力),最后慢慢停下(模拟摩擦力)。

1. 先理解核心物理逻辑(不用怕,就3个公式)

我们不用深究物理原理,记住3个关键逻辑,代码就能对应上:

重力:粒子下落时,速度会越来越快(加速度恒定),列如每帧速度增加0.5。

• 弹力:粒子碰到地面后,速度会反向(向下变向上),但会“衰减”(列如反弹速度是撞击速度的0.7倍,模拟能量损失)。

• 位置更新:粒子的新位置 = 旧位置 + 速度(每帧更新一次,形成动画)。

2. 完整代码+逐行解释(复制就能跑)

新建文件particle_fall.py,复制以下代码,我会在关键处加注释,跟着看就能懂:

# 导入需要的库

import pygame

import math

# 1. 初始化pygame和设置窗口

pygame.init()

WIDTH, HEIGHT = 800, 600 # 窗口宽高

screen = pygame.display.set_mode((WIDTH, HEIGHT))


pygame.display.set_caption(“《代码本色》案例1:粒子下落与反弹”)

clock = pygame.time.Clock() # 控制帧率的时钟

# 2. 定义粒子类(核心!封装粒子的属性和行为)

class Particle:

def __init__(self, x, y, radius):

# 粒子初始位置(x,y)

self.x = x

self.y = y

# 粒子半径(大小)

self.radius = radius

# 粒子速度(x方向初始为0,y方向初始为0,即刚开始不动)

self.velocity_x = 0

self.velocity_y = 0

# 重力加速度(控制下落速度的增加幅度,越大下落越快)

self.gravity = 0.5

# 弹力系数(0-1之间,0不反弹,1完全反弹)

self.bounce = 0.7

# 摩擦力(0-1之间,0无摩擦,1很快停下)

self.friction = 0.98

# 更新粒子的位置和速度(每帧都会调用)

def update(self):

# 1. 应用重力:y方向速度增加(向下为正方向)

self.velocity_y += self.gravity

# 2. 应用摩擦力:x方向速度衰减(让粒子慢慢停下)

self.velocity_x *= self.friction

# 3. 更新位置:新位置 = 旧位置 + 速度

self.x += self.velocity_x

self.y += self.velocity_y

# 4. 碰撞检测:碰到地面(y方向超过窗口底部-半径)

if self.y + self.radius > HEIGHT:

# 让粒子停在地面上(不穿过地面)

self.y = HEIGHT – self.radius

# 反弹:y方向速度反向,并乘以弹力系数(能量损失)

self.velocity_y *= -self.bounce

# (可选)碰到左右边界也反弹

if self.x + self.radius > WIDTH or self.x – self.radius < 0:

self.velocity_x *= -self.bounce

# 绘制粒子(在屏幕上显示)

def draw(self, screen):

pygame.draw.circle(screen, (30, 144, 255), # 蓝色(RGB值)

(int(self.x), int(self.y)), # 位置(转成整数,避免报错)

self.radius) # 半径

# 3. 创建粒子实例(可以改参数玩一玩)

# 列如:在窗口顶部中间,创建一个半径20的粒子

particle = Particle(x=WIDTH // 2, y=50, radius=20)

# 4. 主循环(动画的“心脏”,每帧都会执行)

running = True

while running:

# 控制帧率:每秒60帧(避免动画太快或太慢)

clock.tick(60)

# 处理退出事件(点击窗口右上角叉号关闭)

for event in pygame.event.get():

if event.type == pygame.QUIT:

running = False

# (可选)点击鼠标,在点击位置创建新粒子

if event.type == pygame.MOUSEBUTTONDOWN:

mouse_x, mouse_y = pygame.mouse.get_pos()

particle = Particle(x=mouse_x, y=mouse_y, radius=20)

# 填充背景色(每次填充都会覆盖上一帧,避免粒子留下轨迹)

screen.fill((255, 255, 255)) # 白色背景

# 更新粒子状态(位置、速度)

particle.update()

# 绘制粒子

particle.draw(screen)

# 更新屏幕显示(把绘制的内容展示出来)

pygame.display.flip()

# 退出pygame

pygame.quit()

3. 运行代码+修改参数玩出花样(这步最关键!)

双击运行particle_fall.py,你会看到:蓝色粒子从屏幕顶部落下,碰到底部后弹起,弹起高度越来越低,最后慢慢停下——这就是《代码本色》里最基础的“重力+弹力”效果!

目前别停,试着改代码里的参数,玩出不同效果:

• 把self.gravity = 0.5改成1:粒子下落速度会变快,像“超重”一样。

用Python玩转《The Nature of Code》 实现物理世界 新手也能轻松上手

• 把self.bounce = 0.7改成0.9:粒子反弹高度会更高,接近“几乎不损失能量”。

• 把self.friction = 0.98改成0.8:粒子左右移动时会很快停下,像“在粘土地上运动”。

改完再运行,你会直观感受到物理参数对效果的影响——这比死记公式有用多了,也是《The Nature of Code》的核心学习方法。

四、进阶:从“单个粒子”到“粒子系统”,1行代码生成100个下落的雨滴

学会了单个粒子,我们再进阶一步:实现《代码本色》里的“粒子系统”,列如生成100个粒子,模拟“雨滴下落”的效果。

实则很简单,只需要在之前的代码基础上,用一个列表来存储多个粒子,再循环更新和绘制就行。

完整进阶代码(复制就能跑)

新建particle_system.py,代码如下(关键修改处已标红):

import pygame

import math

import random # 新增:用来随机生成粒子的位置和大小

pygame.init()

WIDTH, HEIGHT = 800, 600

screen = pygame.display.set_mode((WIDTH, HEIGHT))


pygame.display.set_caption(“《代码本色》
案例2:粒子系统(雨滴效果)”)

clock = pygame.time.Clock()

class Particle:

def __init__(self, x, y, radius):

self.x = x

self.y = y

self.radius = radius

self.velocity_x = 0

# 新增:雨滴初始速度随机(让下落更自然)

self.velocity_y = random.randint(2, 5)

self.gravity = 0.1 # 雨滴重力小一点,更真实

self.bounce = 0.1 # 雨滴碰到地面几乎不反弹

self.friction = 0.99

def update(self):

self.velocity_y += self.gravity

self.velocity_x *= self.friction

self.x += self.velocity_x

self.y += self.velocity_y

# 新增:雨滴落到地面后,重新回到顶部(循环效果)

if self.y + self.radius > HEIGHT:

self.y = -self.radius # 从顶部外重新落下

self.x = random.randint(self.radius, WIDTH – self.radius) # 随机x位置

self.velocity_y = random.randint(2, 5) # 重置速度

def draw(self, screen):

# 雨滴用浅蓝色,半透明效果(最后一个参数是透明度,0-255)

pygame.draw.circle(screen, (173, 216, 230, 180),

(int(self.x), int(self.y)),

self.radius)

# 3. 关键修改:创建粒子系统(用列表存储100个粒子)

particle_system = []

for _ in range(100): # 生成100个粒子

x = random.randint(2, WIDTH – 2) # 随机x位置

y = random.randint(-HEIGHT, 0) # 初始在屏幕顶部外

radius = random.randint(1, 3) # 雨滴大小随机(1-3像素)

particle_system.append(Particle(x, y, radius)) # 加入列表

# 4. 主循环修改:循环更新和绘制所有粒子

running = True

while running:

clock.tick(60)

for event in pygame.event.get():

if event.type == pygame.QUIT:

running = False

screen.fill((0, 0, 0)) # 黑色背景,突出雨滴

# 循环更新所有粒子

for particle in particle_system:

particle.update()

# 循环绘制所有粒子

for particle in particle_system:

particle.draw(screen)

pygame.display.flip()

pygame.quit()

运行这段代码,你会看到:黑色背景下,100个浅蓝色的“雨滴”从顶部落下,落到地面后又会从顶部随机位置重新落下——这就是一个简单的“粒子系统”,也是《The Nature of Code》第二章的核心内容。

你还可以继续改:列如把random.randint(2,5)改成random.randint(1,8),让雨滴速度差异更大;把粒子颜色改成(255,255,255)(白色),背景改成(0,0,139)(深蓝色),模拟“下雪”效果。

用Python玩转《The Nature of Code》 实现物理世界 新手也能轻松上手

五、学会这些,你能做什么?(新手也能落地的3个方向)

看到这里,你可能会问:学这些“粒子”“物理”有什么用?实则能落地的方向许多,新手也能上手:

1. 数据可视化:把粒子和数据结合,列如用粒子的大小表明数据值,用粒子的运动表明数据变化(列如股票价格波动、人口流动),比静态图表更生动。

2. 小游戏开发:列如做一个“接球”游戏,用鼠标控制挡板,接住下落的粒子;或者做一个“弹球”游戏,让粒子碰撞反弹,这些都能用我们今天学的代码改出来。

3. 动态壁纸/艺术效果:列如生成“火焰”“烟花”“水流”的效果(《The Nature of Code》里有专门章节),导出成视频,就能当动态壁纸。

用Python玩转《The Nature of Code》 实现物理世界 新手也能轻松上手

六、给新手的学习提议(避免走弯路)

1. 不要急着“啃全书”:《The Nature of Code》内容许多,先从“粒子系统”“力的应用”这两章入手,每章吃透1-2个案例,比囫囵吞枣强。

2. 多改代码,少背代码:列如今天的案例,试着加个“风力”(给velocity_x加个恒定值),或者让粒子颜色随速度变化,改的过程中才能理解逻辑。

3. 遇到问题先“看效果”:如果粒子穿过地面、不反弹,先打印self.y和self.velocity_y的值,看每帧的变化,很快就能找到问题(列如重力没加上、碰撞检测条件错了)。

今天我们用Python复刻了《The Nature of Code》的核心案例,从单个粒子到粒子系统,你会发现:用代码还原物理世界,实则没那么难,而且越玩越有意思。

接下来,你可以试着实现“粒子跟随鼠标”(给粒子加一个“指向鼠标的力”),或者“粒子碰撞”(两个粒子碰到后反弹),这些我会在后续文章里详细讲。

用Python玩转《The Nature of Code》 实现物理世界 新手也能轻松上手

如果觉得今天的教程有用,欢迎点赞+关注,后续会持续更新《The Nature of Code》的Python实现案例,从新手到进阶,一起用代码“创造物理世界”!

#理想销量又创新高凭什么#​#对头条购物避雷#​#爆料#​#p y t hon##艺周刊画坛风云榜#​

© 版权声明

相关文章

1 条评论

您必须登录才能参与评论!
立即登录
  • 头像
    冬至小糕 投稿者

    收藏了,感谢分享

    无记录