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
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: