PYTHON & PYGAME 如何向鼠标位置移动和旋转多边形?



编辑:旋转对我来说不再重要——只是运动。我仍然很好奇,很想知道如何进行轮换。

def angle_between(p1, p2):
    ang1 = np.arctan2(*p1[::-1])
    ang2 = np.arctan2(*p2[::-1])
    return (ang1 - ang2) % (2 * np.pi)  

class Minion:  # Shape: Triangle
        def __init__(self):
            self.rotation = 0
            self.position = (200,200)
            self.radius = 50
            self.vertices = ((1,1), (10,10), (1,10))
        def determine_vertices(self):
            x = self.position[0]
            y = self.position[1]
            target_pos = pygame.mouse.get_pos()
            x2 = target_pos[0]
            y2 = target_pos[1]
            # Will start off pointing to the right (pre-rotation)
            vertex_A = (x + self.radius, y)
            vertex_B = (x + (cos(2*pi/3))*self.radius, y + (sin(2*pi/3))*self.radius)
            vertex_C = (x + (cos(4*pi/3))*self.radius, y + (sin(4*pi/3))*self.radius)
            self.vertices = (vertex_A,vertex_B,vertex_C)  # NOT YET ROTATED
            # Now let's find the angle between my location and the target location
            self.rotation = angle_between((x,y),(x2,y2))
            # Here is where I am stuck

好的,所以我在旋转顶点之前找到了顶点的位置,并且还找到了我想将其旋转的角度(以弧度为单位)。以下是我查看的链接:

我不是在寻找的结果

不明白/不知道如何转换为我的代码

用图形数据代替原始数据

编辑:我已经将顶点公式更改为旋转,但它们旋转的方向错误且速度太快。我不知道为什么。这是代码:

vertex_A = (x + (cos(self.rotation))*self.radius, y + (sin(self.rotation))*self.radius)
vertex_B = (x + (cos((2*pi/3) + self.rotation))*self.radius, y + (sin((2*pi/3) + self.rotation))*self.radius)
vertex_C = (x + (cos((4*pi/3) + self.rotation))*self.radius, y + (sin((4*pi/3) + self.rotation))*self.radius)

要将对象移向鼠标,可以使用矢量。只需从鼠标位置中减去位置,对生成的向量进行归一化,并以所需的速度将其多变。这为您提供了速度矢量,您可以将其添加到每帧self.pos(同时更新用作 blit 位置和碰撞检测的矩形)。

调用 Vector2.as_polar 方法(它返回极坐标)以获取矢量的角度,然后使用它来旋转原始图像。

import pygame as pg
from pygame.math import Vector2

class Entity(pg.sprite.Sprite):
    def __init__(self, pos, *groups):
        super().__init__(*groups)
        self.image = pg.Surface((50, 30), pg.SRCALPHA)  # A transparent image.
        # Draw a triangle onto the image.
        pg.draw.polygon(self.image, pg.Color('dodgerblue2'),
                        ((0, 0), (50, 15), (0, 30)))
        # A reference to the original image to preserve the quality.
        self.orig_image = self.image
        self.rect = self.image.get_rect(center=pos)
        self.vel = Vector2(0, 0)
        self.pos = Vector2(pos)
    def update(self):
        # Subtract the pos vector from the mouse pos to get the heading,
        # normalize this vector and multiply by the desired speed.
        self.vel = (pg.mouse.get_pos() - self.pos).normalize() * 5
        # Update the position vector and the rect.
        self.pos += self.vel
        self.rect.center = self.pos
        # Rotate the image.
        # `Vector2.as_polar` returns the polar coordinates (radius and angle).
        radius, angle = self.vel.as_polar()
        self.image = pg.transform.rotozoom(self.orig_image, -angle, 1)
        self.rect = self.image.get_rect(center=self.rect.center)

def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    all_sprites = pg.sprite.Group()
    entity = Entity((100, 300), all_sprites)
    done = False
    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
        all_sprites.update()
        screen.fill((30, 30, 30))
        all_sprites.draw(screen)
        pg.display.flip()
        clock.tick(30)

if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()

最新更新