首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用PyGame显示PyMunk

使用PyGame显示PyMunk
EN

Stack Overflow用户
提问于 2017-08-28 05:01:03
回答 2查看 2.6K关注 0票数 1

我正在尝试学习PyMunk,我使用了他们在网站上的基本示例:

代码语言:javascript
复制
import pymunk

space = pymunk.Space()
space.gravity = 0,-1000

body = pymunk.Body(1,1666)
body.position = 50,100

poly = pymunk.Poly.create_box(body)
space.add(body, poly)

while True:
    space.step(0.02)

但它不会创建窗口,也不会显示任何内容。如何使用PyGame创建图形窗口?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-28 06:06:58

这个例子所做的是创建一个模拟,在里面添加一个盒子形状的对象,然后无限地运行模拟。代码不会打印或绘制任何内容,因此您实际上看不到输出。为了更好地理解屏幕上的内容,我建议您从教程开始:http://www.pymunk.org/en/latest/tutorials/SlideAndPinJoint.html

Pymunk是一个二维刚体物理库,这意味着它所做的是模拟物体如何在二维中移动和相互作用。它不是为在屏幕上绘图或阅读输入而制作的。

当然,您可以按原样使用它,而不需要其他任何东西,只需打印出模拟结果。但更常见的是,你想要在屏幕上绘制、读取输入等等。要做到这一点,一种方法是使用游戏库Pygame,它可以帮助绘制到屏幕上,读取输入,有一个游戏循环等。

Pymunk本身确实有一些辅助函数,因此您可以轻松地将其与Pygame (和其他几个库)连接起来,但这不是核心部分。通常,当你想要一些快速的东西,比如原型,并且你不需要定制绘图时,这些帮助器函数是很好的。

现在,这就是说,如果你想看到一些东西,你可以在while循环中添加一条print语句,所以它是这样的:

代码语言:javascript
复制
while True:
    space.step(0.02)
    print(body.position)

然后,它将打印出球的位置在模拟的每一步,您可以看到它一直在变化(因为在空间上设置的重力)。

Pymunk中包含了更多的高级示例,它们既是交互式的,又可以在屏幕上显示一些东西。这些示例主要依赖于Pygame或Pyglet,但如果您想使用不同的库,则原理是相同的。

票数 4
EN

Stack Overflow用户

发布于 2017-08-29 02:22:38

这里有一个示例,展示了我如何将Pymunk与pygame结合使用。Entity类是一个pygame.sprite.Sprite子类,我将pymunk.Bodypymunk.Shape以及对pm.Space的引用附加到该类,以便可以在其中添加和删除be和shapes。精灵矩形的位置在每一帧都被设置为self.body.position,这样我们就可以获得正确的self.image位置,并且可以通过调用self.sprite_group.draw(self.screen)来简单地绘制所有精灵。

代码语言:javascript
复制
import math

import pygame as pg
import pymunk as pm
from pymunk import Vec2d


def flipy(p):
    """Convert chipmunk coordinates to pygame coordinates."""
    return Vec2d(p[0], -p[1]+600)


class Entity(pg.sprite.Sprite):

    def __init__(self, pos, space):
        super().__init__()
        self.image = pg.Surface((46, 52), pg.SRCALPHA)
        pg.draw.polygon(self.image, (0, 50, 200),
                        [(0, 0), (48, 0), (48, 54), (24, 54)])
        self.orig_image = self.image
        self.rect = self.image.get_rect(topleft=pos)
        vs = [(-23, 26), (23, 26), (23, -26), (0, -26)]
        mass = 1
        moment = pm.moment_for_poly(mass, vs)
        self.body = pm.Body(mass, moment)
        self.shape = pm.Poly(self.body, vs)
        self.shape.friction = .9
        self.body.position = pos
        self.space = space
        self.space.add(self.body, self.shape)

    def update(self, dt):
        pos = flipy(self.body.position)
        self.rect.center = pos
        self.image = pg.transform.rotate(
            self.orig_image, math.degrees(self.body.angle))
        self.rect = self.image.get_rect(center=self.rect.center)
        # Remove sprites that have left the screen.
        if pos.x < 20 or pos.y > 560:
            self.space.remove(self.body, self.shape)
            self.kill()

    def handle_event(self, event):
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_a:
                self.body.angular_velocity = 5.5
            elif event.key == pg.K_w:
                self.body.apply_impulse_at_local_point(Vec2d(0, 900))


class Game:

    def __init__(self):
        self.done = False
        self.clock = pg.time.Clock()
        self.screen = pg.display.set_mode((800, 600))
        self.gray = pg.Color('gray68')
        self.red = pg.Color('red')

        # Pymunk stuff.
        self.space = pm.Space()
        self.space.gravity = Vec2d(0.0, -900.0)
        self.static_lines = [
            pm.Segment(self.space.static_body, (60, 100), (370, 100), 0),
            pm.Segment(self.space.static_body, (370, 100), (600, 300), 0),
            ]
        for lin in self.static_lines:
            lin.friction = 0.8
        self.space.add(self.static_lines)
        # A sprite group which holds the pygame.sprite.Sprite objects.
        self.sprite_group = pg.sprite.Group(Entity((150, 200), self.space))

    def run(self):
        while not self.done:
            self.dt = self.clock.tick(30) / 1000
            self.handle_events()
            self.run_logic()
            self.draw()

    def handle_events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.done = True
            if event.type == pg.MOUSEBUTTONDOWN:
                self.sprite_group.add(Entity(flipy(event.pos), self.space))
            for sprite in self.sprite_group:
                sprite.handle_event(event)

    def run_logic(self):
        self.space.step(1/60)  # Update physics.
        self.sprite_group.update(self.dt)  # Update pygame sprites.

    def draw(self):
        self.screen.fill(pg.Color(140, 120, 110))
        for line in self.static_lines:
            body = line.body
            p1 = flipy(body.position + line.a.rotated(body.angle))
            p2 = flipy(body.position + line.b.rotated(body.angle))
            pg.draw.line(self.screen, self.gray, p1, p2, 5)
        self.sprite_group.draw(self.screen)
        # Debug draw. Outlines of the Pymunk shapes.
        for obj in self.sprite_group:
            shape = obj.shape
            ps = [pos.rotated(shape.body.angle) + shape.body.position
                  for pos in shape.get_vertices()]
            ps = [flipy((pos)) for pos in ps]
            ps += [ps[0]]
            pg.draw.lines(self.screen, self.red, False, ps, 1)

        pg.display.flip()


if __name__ == '__main__':
    pg.init()
    Game().run()
    pg.quit()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45909318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档