如何设置轴点(旋转中心)pygame.transform.rotate()?

2024-10-01 15:34:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我想围绕一个点而不是中心旋转一个矩形。到目前为止,我的代码是:

import pygame

pygame.init()
w = 640
h = 480
degree = 45
screen = pygame.display.set_mode((w, h))

surf = pygame.Surface((25, 100))
surf.fill((255, 255, 255))
surf.set_colorkey((255, 0, 0))
bigger = pygame.Rect(0, 0, 25, 100)
pygame.draw.rect(surf, (100, 0, 0), bigger)
rotatedSurf = pygame.transform.rotate(surf, degree)
screen.blit(rotatedSurf, (400, 300))

running = True
while running:
    event = pygame.event.poll()
    if event.type == pygame.QUIT:
        running = False
    pygame.display.flip()

我可以改变角度得到不同的旋转,但旋转是围绕中心的。我想设置一个不是矩形中心的点作为旋转点。在


Tags: 代码importeventinitdisplay中心screenpygame
3条回答

我也遇到了这个问题,找到了一个简单的解决方案: 你可以创建一个更大的曲面(双倍的长度和双倍的高度),然后将较小的曲面快速转换为更大的曲面,这样的旋转点就是大曲面的中心。现在你可以把大的绕着中心旋转。在

def rotate(img, pos, angle):
    w, h = img.get_size()
    img2 = pygame.Surface((w*2, h*2), pygame.SRCALPHA)
    img2.blit(img, (w-pos[0], h-pos[1]))
    return pygame.transform.rotate(img2, angle)

(如果你要画素描,那就更有意义了,但请相信我:它很管用,而且在我看来,它比其他解决方案更易于使用和理解。)

为了使曲面围绕其中心旋转,我们首先旋转图像,然后获得一个新的矩形,我们将上一个矩形的center坐标传递到该矩形,使其居中。为了绕一个任意点旋转,我们可以做同样的事情,但是我们还必须在中心位置(轴心点)添加一个偏移向量来移动矩形。每次旋转图像时都需要旋转这个向量。在

因此,我们必须将轴心点(图像或精灵的原始中心)存储在元组、列表、向量或rect中,以及偏移向量(我们移动rect的量)并将它们传递给rotate函数。然后我们旋转图像和偏移向量,得到一个新的rect,将pivot+offset作为center参数传递,最后返回旋转后的图像和新的rect。在

enter image description here

import pygame as pg


def rotate(surface, angle, pivot, offset):
    """Rotate the surface around the pivot point.

    Args:
        surface (pygame.Surface): The surface that is to be rotated.
        angle (float): Rotate by this angle.
        pivot (tuple, list, pygame.math.Vector2): The pivot point.
        offset (pygame.math.Vector2): This vector is added to the pivot.
    """
    rotated_image = pg.transform.rotozoom(surface, -angle, 1)  # Rotate the image.
    rotated_offset = offset.rotate(angle)  # Rotate the offset vector.
    # Add the offset vector to the center/pivot point to shift the rect.
    rect = rotated_image.get_rect(center=pivot+rotated_offset)
    return rotated_image, rect  # Return the rotated image and shifted rect.


pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
BG_COLOR = pg.Color('gray12')
# The original image will never be modified.
IMAGE = pg.Surface((140, 60), pg.SRCALPHA)
pg.draw.polygon(IMAGE, pg.Color('dodgerblue3'), ((0, 0), (140, 30), (0, 60)))
# Store the original center position of the surface.
pivot = [200, 250]
# This offset vector will be added to the pivot point, so the
# resulting rect will be blitted at `rect.topleft + offset`.
offset = pg.math.Vector2(50, 0)
angle = 0

running = True
while running:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            running = False

    keys = pg.key.get_pressed()
    if keys[pg.K_d] or keys[pg.K_RIGHT]:
        angle += 1
    elif keys[pg.K_a] or keys[pg.K_LEFT]:
        angle -= 1
    if keys[pg.K_f]:
        pivot[0] += 2

    # Rotated version of the image and the shifted rect.
    rotated_image, rect = rotate(IMAGE, angle, pivot, offset)

    # Drawing.
    screen.fill(BG_COLOR)
    screen.blit(rotated_image, rect)  # Blit the rotated image.
    pg.draw.circle(screen, (30, 250, 70), pivot, 3)  # Pivot point.
    pg.draw.rect(screen, (30, 250, 70), rect, 1)  # The rect.
    pg.display.set_caption('Angle: {}'.format(angle))
    pg.display.flip()
    clock.tick(30)

pg.quit()

下面是一个带有pygame.sprite.Sprite的版本:

^{pr2}$

我同意梅金和斯科尔。但我也不得不承认,在阅读了他们的答案后,我无法真正掌握这个概念。然后我发现这个game-tutorial是关于一个在边缘旋转的佳能。在

在运行它之后,我仍然有一些问题在心里,但后来我发现他们用在大炮上的图像是其中一部分。在

PNG Cannon image that was centered around its pivot.

图像不是围绕着大炮的中心,而是围绕着轴心点,图像的另一半是透明的。在那次顿悟之后,我把同样的方法应用到我的虫子腿上,它们现在都工作得很好。这是我的轮换代码:

def rotatePivoted(im, angle, pivot):
    # rotate the leg image around the pivot
    image = pygame.transform.rotate(im, angle)
    rect = image.get_rect()
    rect.center = pivot
    return image, rect

希望这有帮助!在

相关问题 更多 >

    热门问题