PyMunk
PyMunk
是一个模拟物理的库。
注意,PyMunk只是进行物理模拟,不包含可视化的功能。如果需要可视化,可使用pygame等库。
可用pip安装pymunk
pip install pymunk
pymunk中的概念:
-
space
: 物理空间。 包含gravity
模拟重力,update
更新空间。 -
Body
: 原子物体(一个点,没有形状),受到力的影响。 -
Shape
:形状,包围在Body
周围,用于检测碰撞。
pymunk中有3种类型的Body
:
- static:静止的,不会移动,但是可以产生碰撞。
- dynamic:动态的,受到力的影响。
- kinematic:受玩家控制(或非物理控制)的影响。
模拟的过程
- 创建空间
space = pymunk.Space()
space.gravity = (0.0, 100.0)
- 创建Body和shape, 并加入到空间中
def create_apple(space, pos):
body = pymunk.Body(mass=1, moment=10, body_type=pymunk.Body.DYNAMIC) # DYNAMIC 类型的物体会受到力的影响
body.position = pos
shape = pymunk.Circle(body, radius=10)
space.add(body, shape)
return shape
(如果使用pygame可视化)绘制物体:
def draw_apple(apples):
for apple in apples:
pos_x = int(apple.body.position.x)
pos_y = int(apple.body.position.y)
pygame.draw.circle(screen, (255, 0, 0), (pos_x, pos_y), 10)
- 更新空间
...
# 在每一帧中更新空间
space.step(1/60.0)
案例
下面是一个完整示例,模拟苹果掉落的过程。
import sys
import pygame
import pymunk
pygame.init()
screen_size = (800, 600)
screen = pygame.display.set_mode(screen_size)
clock = pygame.time.Clock()
space = pymunk.Space()
space.gravity = (0.0, 100.0)
def create_apple(space, pos):
body = pymunk.Body(mass=1, moment=10, body_type=pymunk.Body.DYNAMIC) # DYNAMIC 类型的物体会受到力的影响
body.position = pos
shape = pymunk.Circle(body, radius=10)
space.add(body, shape)
return shape
def draw_apple(apples):
for apple in apples:
pos_x = int(apple.body.position.x)
pos_y = int(apple.body.position.y)
pygame.draw.circle(screen, (255, 0, 0), (pos_x, pos_y), 10)
def create_static_ball(space, pos):
body = pymunk.Body(body_type=pymunk.Body.STATIC) # STATIC 类型的物体 不会移动
body.position = pos
shape = pymunk.Circle(body, radius=10)
space.add(body, shape)
return shape
def draw_balls(balls):
for ball in balls:
pos_x = int(ball.body.position.x)
pos_y = int(ball.body.position.y)
pygame.draw.circle(screen, (0, 255, 0), (pos_x, pos_y), 10)
apples =[]
balls = []
balls.extend([create_static_ball(space, (400, 300)),
create_static_ball(space, (500, 400))
])
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
apple = create_apple(space, pos)
apples.append(apple)
screen.fill((35, 35, 35))
draw_apple(apples)
draw_balls(balls)
space.step(1/60.0)
pygame.display.flip()
clock.tick(60)