我在 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 渲染玩家的纹理,将来可以用图像替换
您可以简单地不在
debug_draw
函数中绘制 Pymunk 主体。由于您使用的是 Pymunk 的调试绘图,因此您可以通过将回调函数传递给 debug_draw
方法来排除某些形状的绘制。
试试这个:
def draw_shapes(space, shapes, *args, **kwargs):
for shape in shapes:
if hasattr(shape, 'color'):
if shape.color[3] != 0:
pymunk.pygame_util.draw_shape(space.debug_screen, shape, *args, **kwargs)
# Modify the debug draw line to exclude drawing the player's body
space.debug_draw(draw_option, draw_shapes=[segment_shape, *all_sprites.sprites()[0].shape])
此修改将排除绘制
segment_shape
以及与玩家身体相关的形状,从而仅从 Pygame 渲染玩家的纹理。