Pygame 使精灵面朝鼠标

4 投票
5 回答
9579 浏览
提问于 2025-04-16 21:59

我刚开始接触Pygame,但对Python还算有点了解。我正在制作一个俯视视角的僵尸射击游戏。
我已经让角色在按下箭头键时可以移动了。但现在我需要让玩家的角色朝着鼠标指针的方向看,而不是每次都要点击屏幕。
有没有人能帮帮我?

5 个回答

0
_, angle = (pg.mouse.get_pos()-self.pos).as_polar()

这一行代码首先计算了一个指向鼠标位置的向量(self.pos 必须是一个 pygame.math.Vector2 类型的对象)。接着,.as_polar() 方法会返回这个向量的极坐标,包括距离和角度。最后,由于pygame的y轴是反向的,所以我们使用负角度来旋转精灵的图像,并重新计算它的矩形区域。

import pygame as pg


class Player(pg.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pg.Surface((50, 30), pg.SRCALPHA)
        pg.draw.polygon(
            self.image,
            pg.Color('dodgerblue1'),
            ((1, 1), (49, 15), (1, 29)))
        self.orig_img = self.image
        self.rect = self.image.get_rect(center=pos)
        self.pos = pg.math.Vector2(pos)
        self.vel = pg.math.Vector2(0, 0)

    def update(self):
        self.rotate()
        self.pos += self.vel
        self.rect.center = self.pos

    def rotate(self):
        _, angle = (pg.mouse.get_pos()-self.pos).as_polar()
        self.image = pg.transform.rotozoom(self.orig_img, -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()
    all_sprites.add(Player((300, 200)))

    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()

math.atan2 也可以作为一种替代方法。

def rotate(self):
    rel_x, rel_y = pg.mouse.get_pos() - self.pos
    angle = -math.degrees(math.atan2(rel_y, rel_x))
    self.image = pg.transform.rotozoom(self.orig_img, angle, 1)
    self.rect = self.image.get_rect(center=self.pos)
1
import math

mouseX, mouseY = pygame.mouse.get_pos()
playerX, playerY = player.get_pos()

angle = math.atan2(playerX-mouseX, playerY-mouseY)

你可能需要调整一下减法的顺序(比如,可能是鼠标位置减去玩家位置),或者在使用atan2函数时,x和y参数的顺序(比如,可能需要把y的差值作为第一个参数,而不是x的差值)。不过这要看你使用的坐标系统是怎样的。

4
for event in pygame.event.get():
    if event.type == MOUSEMOTION:
        mousex, mousey = event.pos
        # build a vector between player position and mouse position
        moveVector = (mousex-playerx, mousey-playery)

        """
        compute the angle of moveVector from current vector that player is facing (faceVector).
        you should be keeping and updating this unit vector, with each mouse motion
        assume you have initial facing vector as (1,0) - facing East
        """

        # compute angle as in [1]

        # rotate the image to that angle and update faceVector

[1] - 如何找到两个向量之间的角度: http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm

当你以小角度旋转图像时,图像可能会失去质量。这个问题在Pygame的文档中有讨论:http://pygame.org/docs/ref/transform.html#pygame.transform.rotate

撰写回答