Pymunk是一个用于2D物理模拟的Python库,它基于Chipmunk物理引擎。Pymunk提供了一种方便的方式来模拟刚体、碰撞和约束,并且可以与Pygame等Python游戏开发库结合使用。
安装:
pip install pymunk
1.模拟物理球体自由跌落
import pygame
import pymunk
import random
pygame.init()
screen_width, screen_height = 600, 600
screen = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()
space = pymunk.Space()
space.gravity = (0, 900)
def create_ball():
mass = 1
radius = 20
x = random.randint(radius, screen_width - radius)
y = random.randint(radius, screen_height - radius)
body = pymunk.Body(mass, pymunk.moment_for_circle(mass, 0, radius))
body.position = x, y
shape = pymunk.Circle(body, radius)
shape.elasticity = 0.95
space.add(body, shape)
for _ in range(10):
create_ball()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
screen.fill((255, 255, 255))
space.step(1/60.0)
for body in space.bodies:
for shape in body.shapes:
if isinstance(shape, pymunk.Circle):
pos = int(body.position.x), int(body.position.y)
pygame.draw.circle(screen, (0, 0, 0), pos, int(shape.radius))
# 检测碰撞边界
if pos[0] < shape.radius or pos[0] > screen_width - shape.radius:
body.velocity = (-body.velocity.x, body.velocity.y)
if pos[1] < shape.radius or pos[1] > screen_height - shape.radius:
body.velocity = (body.velocity.x, -body.velocity.y)
pygame.display.flip()
clock.tick(60)
2.模拟流水
import pygame
import pymunk
# 初始化 Pygame
pygame.init()
# 设置屏幕大小
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Water Effect")
# 颜色
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
# 初始化 Pymunk 空间和重力
space = pymunk.Space()
space.gravity = (0, -1000)
# 创建地面
ground = pymunk.Segment(space.static_body, (0, 50), (WIDTH, 50), 5)
ground.friction = 0.5
space.add(ground)
# 创建水滴粒子
def create_particle(x, y):
body = pymunk.Body(1, 1)
body.position = x, y
shape = pymunk.Circle(body, 2)
shape.elasticity = 0.5
shape.friction = 0.5
space.add(body, shape)
return body
# 游戏循环
running = True
clock = pygame.time.Clock()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 创建新的水滴
mouse_pos = pygame.mouse.get_pos()
if pygame.mouse.get_pressed()[0]:
create_particle(*mouse_pos)
# 更新物理空间
space.step(1/60)
# 绘制屏幕
screen.fill(WHITE)
for body in space.bodies:
for shape in body.shapes:
if isinstance(shape, pymunk.Circle):
pos = int(body.position.x), int(HEIGHT - body.position.y)
pygame.draw.circle(screen, BLUE, pos, int(shape.radius), 0)
# 刷新屏幕
pygame.display.flip()
clock.tick(60)
# 退出 Pygame
pygame.quit()
参数简介:
质量 (mass):物体的质量,影响其受到的力和加速度。用法:body.mass = 5 # 将物体的质量设置为5
惯性 (moment):物体的惯性,决定了其对旋转的响应程度。用法:body.moment = 10 # 将物体的惯性设置为10
弹性 (elasticity):用于描述碰撞后能量损失的程度。用法:shape.elasticity = 0.8 # 设置碰撞形状的弹性为0.8
摩擦系数 (friction):描述两个物体之间相互滑动的难度程度。用法:shape.friction = 0.5 # 设置碰撞形状的摩擦系数为0.5
线速度 (velocity):物体在空间中的线速度,即速度的大小和方向。用法:body.velocity = (10, 0) # 设置物体的线速度为(10, 0)
角速度 (angular_velocity):物体的角速度,即绕中心点的旋转速度。用法:body.angular_velocity = 2.5 # 设置物体的角速度为2.5
位置 (position):物体在空间中的位置。用法:body.position = (100, 200) # 将物体移动到坐标(100, 200)处
弹簧常数 (stiffness):弹簧的刚度,影响弹簧的形变程度。用法:spring.stiffness = 1000 # 设置弹簧的刚度为1000
阻尼系数 (damping):用于减少物体的速度,模拟物体在空气或液体中运动时受到的阻力。用法:body.damping = 0.2 # 设置阻尼系数为0.2
转动惯量 (moment_of_inertia):表示物体抵抗旋转的能力。用法:body.moment_of_inertia = 20 # 设置物体的转动惯量为20
形状 (shape):描述物体的形状,可以是圆形、矩形、多边形等。用法:circle_shape = pymunk.Circle(body, radius) # 创建一个圆形形状
碰撞组 (collision_type):用于标识不同类型的碰撞对象,以便进行碰撞检测和处理。用法:shape.co