Pymunk Body与精灵图像旋转方向相反问题求助
解决精灵与Pymunk Body旋转方向相反的问题
问题根源很直接:Pymunk中Body的角度以逆时针旋转为正方向,但Pygame的pygame.transform.rotate()方法是以顺时针旋转为正方向,直接复用Body的角度值就会导致旋转方向完全相反。
另外你当前的精灵偏移是硬编码数值,旋转后图片尺寸会变化,硬编码会导致精灵位置偏移不准,需要用旋转后图片的中心来计算偏移量。
修改后的核心代码部分
把旋转和绘制的代码替换成下面这段:
angle_degrees = math.degrees(playerbody.angle) # 取角度的负数,反转Pygame的旋转方向,和Pymunk保持一致 rotated_fish = pygame.transform.rotate(fish, -angle_degrees) # 获取旋转后图片的矩形,用来计算中心偏移 rotated_rect = rotated_fish.get_rect() # 以Body的位置为中心,对齐精灵中心 draw_pos = ( round(playerbody.position.x - rotated_rect.centerx), round(playerbody.position.y - rotated_rect.centery) ) screen.blit(rotated_fish, draw_pos)
完整修改后的代码
__docformat__ = "reStructuredText" import random import math import pygame import pymunk import pymunk.pygame_util from pymunk import Vec2d def main(): pygame.init() screen = pygame.display.set_mode((1067, 600)) clock = pygame.time.Clock() running = True direct = 0 ### Physics stuff space = pymunk.Space() space.gravity = (0.0, 900.0) draw_options = pymunk.pygame_util.DrawOptions(screen) fish = pygame.image.load('fish.png') # 提前获取原始图片的矩形,可选,但方便后续参考 original_fish_rect = fish.get_rect() ### walls and ground static_lines = [ pymunk.Segment(space.static_body, (0, 550), (1067, 550), 10), pymunk.Segment(space.static_body, (0, 0), (0, 550), 10), pymunk.Segment(space.static_body, (1067, 0), (1067, 550), 10) ] for line in static_lines: line.elasticity = 0.7 line.group = 1 line.friction = 1000 space.add(*static_lines) fp = [(7, -10), (-7, -10), (-30, -7),(-40, 0), (-30, 7), (-7, 10), (7, 10), (40, 0)] mass = 100 moment = pymunk.moment_for_poly(mass, fp) playerbody = pymunk.Body(mass, moment) playerbody.position = 533, 400 playershape = pymunk.Poly(playerbody, fp) space.add(playerbody, playershape) while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: running = False elif event.type == pygame.KEYDOWN and event.key == pygame.K_a: direct -= 1 elif event.type == pygame.KEYDOWN and event.key == pygame.K_d: direct += 1 elif event.type == pygame.KEYUP and event.key == pygame.K_a: direct = 0 elif event.type == pygame.KEYUP and event.key == pygame.K_d: direct = 0 elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: playerbody.apply_impulse_at_world_point( (0,-40000), (playerbody.position[0], playerbody.position[1]) ) if direct > 1: direct = 1 if direct < -1: direct = -1 if direct == 1: playerbody.apply_force_at_local_point((200000, 0), (0, 0)) playerbody.apply_force_at_local_point((0, -2900), (-30, 0)) if direct == -1: playerbody.apply_force_at_local_point((-200000, 0), (0, 0)) playerbody.apply_force_at_local_point((0, -2900), (30, 0)) ### Clear screen screen.fill(pygame.Color("white")) ### Draw stuff space.debug_draw(draw_options) ### Update physics dt = 1.0 / 60.0 / 5.0 for x in range(5): space.step(dt) # 修正旋转方向和偏移计算 angle_degrees = math.degrees(playerbody.angle) rotated_fish = pygame.transform.rotate(fish, -angle_degrees) rotated_rect = rotated_fish.get_rect() draw_pos = ( round(playerbody.position.x - rotated_rect.centerx), round(playerbody.position.y - rotated_rect.centery) ) screen.blit(rotated_fish, draw_pos) ### Flip screen pygame.display.flip() clock.tick(50) pygame.display.set_caption("fps: " + str(clock.get_fps())) if __name__ == "__main__": main()
额外说明
- 不需要修改图片源文件,只需要在旋转时取角度的负数即可对齐两个库的旋转方向。
- 用旋转后图片的
get_rect()来计算偏移,能保证无论怎么旋转,精灵中心都和Pymunk Body的位置完全重合,避免硬编码数值导致的偏移错误。
内容的提问来源于stack exchange,提问作者Romdev
相关产品推荐
相关产品推荐

