如何在Pymunk中设置隐形物体?

0 投票
1 回答
42 浏览
提问于 2025-04-12 21:30

我在Pygame上做了一个游戏,并使用Pymunk添加了物理效果,但遇到了一个问题,Pymunk中的物体显示在了Pygame中原本玩家角色的图像上面。怎么让这个物体变得不可见呢?

import pygame
import pymunk.pygame_util
import random
import math


SIZE = WIDTH, HEIGHT = 1000, 600
BACKGROUND_COLOR = (255, 255, 255)
FPS = 30


pygame.init()
pymunk.pygame_util.positive_y_is_up = False


class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.orig_image = pygame.Surface((50, 100), pygame.SRCALPHA)
        self.orig_image.fill((0, 255, 0))
        self.orig_image = pygame.transform.scale(self.orig_image, self.orig_image.get_size())
        self.image = self.orig_image.copy()
        self.rect = self.image.get_rect(center=(500, 500))

        self.vel = 0
        self.angle = 0
        self.vel_speed = 5
        self.rotate_speed = 10

        self.space = pymunk.Space
        self.body = pymunk.Body
        self.shape = pymunk.Poly

    def update(self, display):
        self.vel = 0
        event_key = pygame.key.get_pressed()
        if event_key[pygame.K_UP]:
            self.vel -= self.vel_speed
        if event_key[pygame.K_DOWN]:
            self.vel += self.vel_speed
        if event_key[pygame.K_LEFT]:
            self.angle += self.rotate_speed
        if event_key[pygame.K_RIGHT]:
            self.angle -= self.rotate_speed

        self.body.position += ((self.vel * math.sin(math.radians(self.angle)),
                                self.vel * math.cos(math.radians(self.angle))))
        self.rect.center = self.body.position
        self.body.angle = -math.radians(self.angle)

        self.image = pygame.transform.rotate(self.orig_image, self.angle)
        self.rect = self.image.get_rect(center=self.rect.center)
        display.blit(self.image, self.rect)

    def physics(self, pm_space):
        size = self.rect.size
        mass = 5
        moment = pymunk.moment_for_box(mass, size)
        self.body = pymunk.Body(mass, moment)
        self.shape = pymunk.Poly.create_box(self.body, size)
        self.shape.elasticity = 1
        self.shape.friction = 2
        self.body.position = self.rect.center
        self.space = pm_space
        self.space.add(self.body, self.shape)


pygame.display.set_caption("Pygame")
display = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()

draw_option = pymunk.pygame_util.DrawOptions(display)
space = pymunk.Space()
space.gravity = (0, 0)

segment_shape = pymunk.Segment(space.static_body, (100, 200), (400, 200), 20)
space.add(segment_shape)
segment_shape.elasticity = 1
segment_shape.friction = 1

all_sprites = pygame.sprite.Group()
player = Player()
player.physics(space)
all_sprites.add(player)


def create_square(space, pos):
    square_mass = 1
    square_size = (50, 50)
    square_moment = pymunk.moment_for_box(square_mass, square_size)
    square_body = pymunk.Body(square_mass, square_moment)
    square_body.position = pos
    square_shape = pymunk.Poly.create_box(square_body, square_size)
    square_shape.elasticity = 0.8
    square_shape.friction = 1
    square_shape.color = [random.randrange(256) for i in range(4)]
    space.add(square_body, square_shape)


running = True
while running:
    clock.tick(FPS)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    if pygame.mouse.get_pressed()[0]:
        create_square(space, pygame.mouse.get_pos())

    display.fill((255, 255, 255))

    space.debug_draw(draw_option)
    space.step(3 / FPS)

    all_sprites.update(display)
    all_sprites.draw(display)

    pygame.display.update()
pygame.quit()

我只需要显示Pygame中玩家的图像,未来可以用其他图片替换这个图像。

1 个回答

0

一般来说,Pymunk里的调试绘图功能并不适合处理像这样的复杂情况。它的设计初衷是简单地绘制所有东西,并进行一些小的自定义。如果你需要更复杂的逻辑,最好还是自己手动绘制所有内容。(这意味着你可以直接去掉debug_draw

不过,你可以尝试一些方法:

  1. 把你不想绘制的形状的颜色设置为透明色,也就是把它的透明度设置为0。在你创建方形的时候,把颜色的透明度设置为0(注意,这需要绘图时能够处理透明度,我不太记得在pygame里是怎么处理的):
self.body.position = self.rect.center
self.shape.color = (0,0,0,0)
self.space = pm_space
  1. 调整调试绘图的选项,让它不绘制任何形状(如果你愿意的话,只绘制碰撞和约束):
draw_option = pymunk.pygame_util.DrawOptions(display)
draw_option.flags = pymunk.SpaceDebugDrawOptions.DRAW_CONSTRAINTS
draw_option.flags |= pymunk.SpaceDebugDrawOptions.DRAW_COLLISION_POINTS

撰写回答