我一直在尝试使用 pygame.transform.rotate()
围绕其中心旋转图像,但它不起作用。具体挂起的部分是 rot_image = rot_image.subsurface(rot_rect).copy()
。我得到例外:
ValueError: subsurface rectangle outside surface area
这是用于旋转图像的代码:
def rot_center(image, angle):
"""rotate an image while keeping its center and size"""
orig_rect = image.get_rect()
rot_image = pygame.transform.rotate(image, angle)
rot_rect = orig_rect.copy()
rot_rect.center = rot_image.get_rect().center
rot_image = rot_image.subsurface(rot_rect).copy()
return rot_image
原文由 Miha 发布,翻译遵循 CC BY-SA 4.0 许可协议
简短回答:
当您使用
pygame.transform.rotate
时,与原始图像的大小相比,新旋转图像的大小增加了。您必须确保放置旋转图像,使其中心保持在未旋转图像的中心。为此,获取原始图像的矩形并设置位置。获取旋转图像的矩形,通过原矩形的中心设置中心位置。从函数
red_center
返回一个元组,带有旋转图像和旋转图像的边界矩形:或者写一个旋转和
.blit
图像的函数:长答案:
图像 (
pygame.Surface
) 可以旋转pygame.transform.rotate
。如果这是在循环中逐步完成的,那么图像会失真并迅速增加:
这是因为旋转图像的边界矩形总是大于原始图像的边界矩形(除了一些旋转 90 度的倍数)。
由于多份副本,图像会失真。每次旋转都会产生一个小错误(不准确)。错误的总和在增加,图像在衰减。
这可以通过保留原始图像并将由单个旋转操作生成的图像从原始图像“blit”来解决。
现在图像似乎可以任意改变它的位置,因为图像的大小随着旋转而改变,原点总是图像边界矩形的左上角。
这可以通过比较旋转前后图像的 轴对齐边界框 来补偿。
对于以下数学
pygame.math.Vector2
使用。注意屏幕坐标中的 y 指向屏幕下方,但数学 y 轴点从底部到顶部。这导致在计算过程中必须“翻转”y 轴使用边界框的 4 个角点设置一个列表:
通过
pygame.math.Vector2.rotate
将向量旋转到角点:获取旋转点的最小值和最大值:
通过将旋转框的最小值添加到该位置来计算图像左上角点的“补偿”原点。对于 y 坐标
max_box[1]
是最小值,因为沿 y 轴“翻转”:甚至可以在原始图像上定义一个枢轴。计算从图像中心到枢轴的偏移向量并旋转向量。矢量可以用
pygame.math.Vector2
表示,可以用pygame.math.Vector2.rotate
旋转。请注意pygame.math.Vector2.rotate
的旋转方向与pygame.transform.rotate
的旋转方向相反。因此角度必须倒转:计算从图像中心到枢轴的向量:
旋转矢量
计算旋转图像的中心:
旋转并 blit 图像:
在下面的示例程序中,函数
blitRotate(surf, image, pos, originPos, angle)
执行上述所有步骤并将旋转图像“blit”到表面。surf
是目标表面image
是必须旋转的表面和blit
pos
是目标Surface上的枢轴位置surf
(相对于surf
的左上角)originPos
是枢轴在image
表面上的位置(相对于image
的左上角)angle
是以度为单位的旋转角度这意味着, --- 的第二个参数 (
pos
blitRotate
是窗口中轴心点的位置,第三个参数 (originPos
) 是-的位置旋转 表面 上的枢轴点:最小的例子:
repl.it/@Rabbid76/PyGame-RotateAroundPivot
另见 旋转曲面 和问题的答案: