gpt4 book ai didi

python - 如何在 Pygame 中围绕偏离中心的支点旋转图像

转载 作者:行者123 更新时间:2023-12-03 20:11:39 28 4
gpt4 key购买 nike

我想围绕一个枢轴旋转图像,该枢轴不在 Surface 的中心在 Pygame .
枢轴是图像中的绿色十字:

enter image description here

我知道游戏窗口中枢轴的位置。
我如何在此时跟踪图像并同时围绕该点旋转它。

image = pygame.image.load("boomerang64.png")
pos = (200, 200)
angle = 0

while True:
# [...]

rotate_rect, rotate_image = ???? # rotate around green cross by angle
surf.blit(rotated_image, rotate_rect)
angle += 1

# [...]

最佳答案

首先是 Surface 上枢轴的位置必须定义:

image = pygame.image.load("boomerang64.png") # 64x64 surface
pivot = (48, 21) # position of the pivot on the image
旋转图像时,其大小会增加。我们要比较 axis aligned bounding box旋转前和旋转后的图像。
对于以下数学 pygame.math.Vector2 用来。注意屏幕坐标中的 y 指向屏幕下方,但数学 y 轴点从底部到顶部。这导致在计算过程中必须“翻转”y 轴。请注意 pygame.math.Vector2.rotatepygame.transform.rotate 的旋转方向相反.因此角度必须倒转。
用边界框的 4 个角点设置一个列表,并将向量旋转到角点 pygame.math.Vector2.rotate .最后找到旋转框的最小值。由于 pygame 中的 y 轴指向下方,因此必须通过找到旋转倒置高度的最大值 ("max(rotate(-h))") 来补偿:
计算从图像中心到枢轴的向量:
image_rect = image.get_rect(topleft = (pos[0] - originPos[0], pos[1]-originPos[1]))
offset_center_to_pivot = pygame.math.Vector2(pos) - image_rect.center
旋转偏移向量:
rotated_offset = offset_center_to_pivot.rotate(-angle)
计算旋转图像的中心:
rotated_image_center = (pos[0] - rotated_offset.x, pos[1] - rotated_offset.y)
旋转和 blit 图像:
rotated_image = pygame.transform.rotate(image, angle)
rotated_image_rect = rotated_image.get_rect(center = rotated_image_center)

screen.blit(rotated_image, rotated_image_rect)
在下面的示例程序中,函数 blitRotate(surf, image, pos, originPos, angle)执行上述所有步骤和 blit 旋转到与显示器相关联的 Surface 的图像:
  • surf是目标曲面
  • image是必须旋转的表面和 blit
  • pos是目标曲面上的枢轴位置 surf (相对于 surf 的左上角)
  • originPosimage 上枢轴的位置表面(相对于 image 的左上角)
  • angle是以度为单位的旋转角度


  • import math
    import pygame

    def blitRotate(surf, image, pos, originPos, angle):
    image_rect = image.get_rect(topleft = (pos[0] - originPos[0], pos[1]-originPos[1]))
    offset_center_to_pivot = pygame.math.Vector2(pos) - image_rect.center
    rotated_offset = offset_center_to_pivot.rotate(-angle)
    rotated_image_center = (pos[0] - rotated_offset.x, pos[1] - rotated_offset.y)
    rotated_image = pygame.transform.rotate(image, angle)
    rotated_image_rect = rotated_image.get_rect(center = rotated_image_center)
    surf.blit(rotated_image, rotated_image_rect)

    pygame.init()
    size = (400,400)
    screen = pygame.display.set_mode(size)
    clock = pygame.time.Clock()

    image = pygame.image.load('Boomerang64.png')
    pivot = (48, 21)

    angle, frame = 0, 0
    done = False
    while not done:
    clock.tick(60)
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    done = True
    screen.fill(0)

    pos = (200 + math.cos(frame * 0.05)*100, 200 + math.sin(frame * 0.05)*50)
    blitRotate(screen, image, pos, pivot, angle)

    pygame.draw.line(screen, (0, 255, 0), (pos[0]-20, pos[1]), (pos[0]+20, pos[1]), 3)
    pygame.draw.line(screen, (0, 255, 0), (pos[0], pos[1]-20), (pos[0], pos[1]+20), 3)
    pygame.draw.circle(screen, (0, 255, 0), pos, 7, 0)

    pygame.display.flip()
    frame += 1
    angle += 10

    pygame.quit()
    exit()

    相同的算法可用于 Sprite , 也。
    在这种情况下,位置( self.pos )、枢轴( self.pivot )和角度( self.angle )是类的实例属性。
    update方法 self.rectself.image计算属性。
    最小示例: repl.it/@Rabbid76/PyGame-RotateSpriteAroundOffCenterPivot
    import math
    import pygame

    class SpriteRotate(pygame.sprite.Sprite):

    def __init__(self, imageName, origin, pivot):
    super().__init__()
    self.image = pygame.image.load(imageName)
    self.original_image = self.image
    self.rect = self.image.get_rect(topleft = (origin[0]-pivot[0], origin[1]-pivot[1]))
    self.origin = origin
    self.pivot = pivot
    self.angle = 0

    def update(self):

    # offset from pivot to center
    image_rect = self.original_image.get_rect(topleft = (self.origin[0] - self.pivot[0], self.origin[1]-self.pivot[1]))
    offset_center_to_pivot = pygame.math.Vector2(self.origin) - image_rect.center

    # roatated offset from pivot to center
    rotated_offset = offset_center_to_pivot.rotate(-self.angle)

    # roatetd image center
    rotated_image_center = (self.pos[0] - rotated_offset.x, self.pos[1] - rotated_offset.y)

    # get a rotated image
    self.image = pygame.transform.rotate(self.original_image, self.angle)
    self.rect = self.image.get_rect(center = rotated_image_center)
    self.angle += 10

    pygame.init()
    size = (400,400)
    screen = pygame.display.set_mode(size)
    clock = pygame.time.Clock()

    boomerang = SpriteRotate('Boomerang64.png', (200, 200), (48, 21))
    all_sprites = pygame.sprite.Group(boomerang)

    frame = 0
    done = False
    while not done:
    clock.tick(60)
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    done = True

    pos = (200 + math.cos(frame * 0.05)*100, 200 + math.sin(frame * 0.05)*50)
    boomerang.pos = pos
    all_sprites.update()

    screen.fill(0)

    all_sprites.draw(screen)
    #pygame.draw.line(screen, (0, 255, 0), (pos[0]-20, pos[1]), (pos[0]+20, pos[1]), 3)
    #pygame.draw.line(screen, (0, 255, 0), (pos[0], pos[1]-20), (pos[0], pos[1]+20), 3)
    #pygame.draw.circle(screen, (0, 255, 0), pos, 7, 0)

    pygame.display.flip()
    frame += 1

    pygame.quit()
    exit()

    How do I rotate an image around its center using Pygame?
    How to rotate an image around its center while its scale is getting larger(in Pygame)

    关于python - 如何在 Pygame 中围绕偏离中心的支点旋转图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59909942/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com