python-3.x 可以实现pybox2d和pygame的交互吗?

bf1o4zei  于 4个月前  发布在  Python
关注(0)|答案(1)|浏览(60)

我在Pygame上写了一个Tetris游戏,但是当棋子碰到地板或者其他棋子的沙子时,它们会碎成沙子。我通过pymunk写了这个游戏,但是没有找到一篇关于pymunk物体(沙子)和精灵(下落的人物)相互作用的文章。
下落的人物是通过 pygame sprites 制作的,沙子是通过 box2d objects 制作的。告诉我如何跟踪sprites与box2d对象的接触?
沙作为 * 动态体 * 以圆形的形式产生,并且具有type <class 'Box2D.Box2D.b2Fixture'>

因此,如何跟踪<class 'Box2D.Box2D.b2Fixture'>和pygame精灵的触摸

import pygame
from Box2D.b2 import world, polygonShape, circleShape, staticBody, dynamicBody
import sys, os

PPM = 4.0
TARGET_FPS = 60
TIME_STEP = 1.0 / TARGET_FPS
SCREEN_WIDTH, SCREEN_HEIGHT = 300, 600

pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32)
clock = pygame.time.Clock()

world = world(gravity=(0, -1000))

# walls
ground_body = world.CreateStaticBody(position=(0, 0), shapes=polygonShape(box=(75, 1)))
left_body = world.CreateStaticBody(position=(75, 150), shapes=polygonShape(box=(1, 175)))
right_body = world.CreateStaticBody(position=(0, 150), shapes=polygonShape(box=(1, 175)))

# prepare image for pygame.sprite
def load_image(name, colorkey=None):
    fullname = os.path.join('data/images', name)
    if not os.path.isfile(fullname):
        print(f"Файл с изображением '{fullname}' не найден")
        sys.exit()
    image = pygame.image.load(fullname)

    if colorkey is not None:
        image = image.convert()
        if colorkey == -1:
            colorkey = image.get_at((0, 0))
        image.set_colorkey(colorkey)
    else:
        image = image.convert_alpha()

    return image

# sprite
class SomeFigure(pygame.sprite.Sprite):
    def __init__(self, *groups):
        super().__init__(*groups)
        self.image = load_image("T_blue.png")
        self.rect = self.image.get_rect()
        self.rect.x, self.rect.y = 100, 30

        self.figures_sprites = pygame.sprite.Group()
        self.figures_sprites.add(self)
    
    def render(self):
        self.rect.y += 1
        self.figures_sprites.draw(screen)

figure = SomeFigure()

def create_circles(pos):
    x, y = pos[0] // 4, (600 - pos[1]) // 4
    for step_y in range(0, 60, 16):
        step_y = -step_y // 4
        for step_x in range(0, 60, 16):
            print(x + step_x, y + step_y)
            step_x = step_x // 4
            body = world.CreateDynamicBody(position=(x + step_x, y + step_y))
            circle = body.CreateCircleFixture(radius=1, density=1, friction=1)
            print(type(circle))
        print()

def create_rectangles(pos):
    for step_y in range(0, 60, 15):
        for step_x in range(0, 60, 15):
            body = world.CreateDynamicBody(position=(pos[0] + step_x, pos[1] + step_y), angle=0)
            box = body.CreatePolygonFixture(box=(1, 1), density=1, friction=1)

colors = {staticBody: (255, 255, 255, 255),
          dynamicBody: (127, 127, 127, 127)
}

def my_draw_polygon(polygon, body, fixture):
    vertices = [(body.transform * v) * PPM for v in polygon.vertices]
    vertices = [(v[0], SCREEN_HEIGHT - v[1]) for v in vertices]
    pygame.draw.polygon(screen, colors[body.type], vertices)

polygonShape.draw = my_draw_polygon

def my_draw_circle(circle, body, fixture):
    position = body.transform * circle.pos * PPM
    position = (position[0], SCREEN_HEIGHT - position[1])
    pygame.draw.circle(screen, colors[body.type],
                       [int(x) for x in position], int(circle.radius * PPM))

circleShape.draw = my_draw_circle

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            create_circles(event.pos)
    screen.fill((0, 0, 0, 0))
    for body in world.bodies:
        for fixture in body.fixtures:
            fixture.shape.draw(body, fixture)
    world.Step(TIME_STEP, 10, 10)
    figure.render()
    pygame.display.flip()
    clock.tick(TARGET_FPS)
pygame.quit()

字符串


的数据

hof1towb

hof1towb1#

你可以创建一个大的box2d主体,它具有一个正方形的形状,将适合完整的碎片。在这种情况下,box2d将承担搜索完整的碎片和沙子碎片之间的碰撞的工作。你所要做的就是链接精灵和这个主体。如果你想让主体不旋转,使用setFixedRotation()方法。
如果你不想为棋子创造一个单独的身体,你将很难实现沙子和棋子之间的真实互动(特别是如果棋子像原来的俄罗斯方块那样跳动)。然而,你可以使用一个简单的搜索所有的沙粒,检查每一个与精灵的交集。还有更复杂但更有效的方法,如给定矩形区域的世界查询(AABB查询)

相关问题