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)