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 = posshape = 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 pymunkpygame.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 = posshape = pymunk.Circle(body, radius=10)space.add(body, shape)return shapedef 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 = posshape = pymunk.Circle(body, radius=10)space.add(body, shape)return shapedef 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)