pygame教程实例(五)物理引擎pymunk

上一篇:pygame教程实例(四)小球弹跳(事件)
下一篇:pygame教程实例(六)你从来没玩过的俄罗斯方块

本教程使用python3

在前几个教程中,我们模拟了小球和星球的运动。
但是,在游戏中我们往往会遇到很复杂的物理运动,比如碰撞、旋转、滑轮、绳子、轮子等。这时候如果我们自己写这些就很麻烦了,不过有很多已经写好了的物理模块可以供我们使用,这些模块被叫做物理引擎。
物理引擎可分为2D和3D,顾名思义,2D只是对于二维世界的,比如愤怒的小鸟。而3D就是对于三维世界的了。
今天我介绍的物理引擎pymunk是2D的。
pymunk 官网
pymunk GitHub


一、安装pymunk

使用国内镜像:

pip3 pymunk -i https://mirrors.aliyun.com/pypi/simple

二、简单使用

我们通过一个简单的实例来介绍pymunk的使用

1.导入包

import random

import pygame
from pygame.key import *
from pygame.locals import *
from pygame.color import *

import pymunk
import pymunk.pygame_util

2.创建空间及初始化

# pymunk初始化
space = pymunk.Space()        # 空间
space.gravity = (0.0, -900.0) # 设置重力

# pygame初始化
pygame.init()
screen = pygame.display.set_mode((600, 600))
clock = pygame.time.Clock()
# 在pygame上创建画板
draw_options = pymunk.pygame_util.DrawOptions(screen)

FPS = 60
balls = []  # 所有的球
ticks_to_next_ball = 10  # 多少帧后出现下一个球
exact = 10  # 一帧计算几次

3.创建静态物体

静态实体即固定不动的实体,一般不可被穿过。比如地面和墙。
pymunk.Segment 是静态物体类,我们通过它实例化物体。

注意:pymunk中(0, 0)坐标在左下角,pygame中在左上角

下面的代码将创建两个静态物体。

static_body = space.static_body
static_lines = [
	pymunk.Segment(static_body, (111.0, 280.0), (407.0, 246.0), 0.0),
	pymunk.Segment(static_body, (407.0, 246.0), (407.0, 343.0), 0.0)
]
for line in static_lines:
    line.elasticity = 0.95  # 弹性系数 0-1
    line.friction = 0.9     # 摩擦系数 0-1
space.add(static_lines)

4.创建物体

pymunk.Body 是物体类
pymunk.Circle是圆类(其父类是Shape 形状类)
下面我们写个函数来创建小球

# 创建一个球
def create_ball():
    mass = 10   # 质量
    radius = 25 # 半径
    inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0))
    body = pymunk.Body(mass, inertia)
    x = random.randint(115, 350)
    body.position = x, 400
    shape = pymunk.Circle(body, radius, (0, 0))
    shape.elasticity = 0.95
    shape.friction = 0.9
    space.add(body, shape)
    balls.append(shape)

5.移除物体

从世界中删除物体
space.remove(Shape, Body)

下面这个函数是创建或删除小球

def update_balls():
	global ticks_to_next_ball
    # 根据需要创建/移除球。每帧只调用一次。
    ticks_to_next_ball -= 1
    if ticks_to_next_ball <= 0:
        create_ball()
        ticks_to_next_ball = 100
    # 移除低于100的球
    balls_to_remove = [ball for ball in balls if ball.body.position.y < 100]
    for ball in balls_to_remove:
        space.remove(ball, ball.body)
        balls.remove(ball)

6.写侦听事件

这里我们介绍一下pygame中的截图方法
pygame.image.save(screen, “bouncing_balls.png”)

def my_events():
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        elif event.type == KEYDOWN and event.key == K_ESCAPE:
            exit()
        elif event.type == KEYDOWN and event.key == K_p:
            # 截图
            pygame.image.save(screen, "bouncing_balls.png")

7.其他函数

# 清除屏幕
def clear_screen():
    screen.fill(THECOLORS["white"])

# 画对象
def draw_objects():
    space.debug_draw(draw_options)

8.主循环

space.step(time)
空间运行time秒

while True:
    # 计算下一帧位置
    for x in range(exact):
        space.step(1/FPS/exact)

    my_events()
    update_balls()
    clear_screen()
    draw_objects()
    pygame.display.flip()
    clock.tick(FPS)
    pygame.display.set_caption("fps: " + str(clock.get_fps()))

三、效果


上一篇:pygame教程实例(四)小球弹跳(事件)
下一篇:pygame教程实例(六)你从来没玩过的俄罗斯方块

你可能感兴趣的:(pygame,python,python3,pymunk,物理引擎,教程)