How set invisible body from Pymunk?

45 Views Asked by At

I created a game on Pygame and added physics using Pymunk, but ran into a problem, the body from Pymunk is rendered on top of the original player texture from Pygame. Нow to make this body invisible?

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()

Need to render only the texture of the player from Pygame that in the future can be replaced by an image

1

There are 1 best solutions below

0
viblo On

In general, the debug drawing in Pymunk is not meant for more complex cases like this. The idea is that it draws everything with some minor customizations. If you need more advanced logic, its better to just draw everything by yourself. (Meaning you just remove the debug_draw)

However, there are some things you can try:

  1. Set the color of the shapes you do not want to draw to a color with 0 alpha to make it transparent. Where you create the box shape set the color to 0 alpha (note that this requires alpha to be handled by the drawing, I dont remember exactly how it works in pygame):
self.body.position = self.rect.center
self.shape.color = (0,0,0,0)
self.space = pm_space
  1. Configure the debug draw options to not draw any shapes (but only collisions/constraints if you like:
draw_option = pymunk.pygame_util.DrawOptions(display)
draw_option.flags = pymunk.SpaceDebugDrawOptions.DRAW_CONSTRAINTS
draw_option.flags |= pymunk.SpaceDebugDrawOptions.DRAW_COLLISION_POINTS