Pygame让Sprite面对老鼠

时间:2011-07-21 12:18:10

标签: python sprite pygame

我是Pygame的新手,但有点好的Python,我用俯视图创建一个僵尸射击游戏。
按箭头键时,我设法让角色移动。但是现在我需要让玩家在没有一直点击屏幕的情况下面对鼠标/光标 任何帮助?

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

import math

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

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

您可能必须使用减法的顺序(即,它可能是mousePosition-playerPosition)或x和y参数的顺序为atan2(即,您可能需要将Y差作为第一个参数传递而不是X)但这取决于你的坐标系。

答案 2 :(得分:0)

工作代码:

import pygame, sys, math
from pygame.locals import *


#converte in base ai gradi le cordinate x,y
#maxXY= surface MaxXY
#gradoRot = grado di rotazione
#distXY = spostamento in x,y lungo il vettore di cordinate locali dalle cordinate x,y

#movement from one point to another
def Move(t0,t1,psx,psy,speed):
    global mx
    global my

    speed = speed

    distance = [t0 - psx, t1 - psy]
    norm = math.sqrt(distance[0] ** 2 + distance[1] ** 2)
    direction = [distance[0] / norm, distance[1 ] / norm]

    bullet_vector = [direction[0] * speed, direction[1] * speed]
    return bullet_vector
# Main Function
if __name__ == '__main__':
    pygame.init()
    FPS = 30 # frames per second setting
    fpsClock = pygame.time.Clock()
    # set up the window
    DISPLAYSURF = pygame.display.set_mode((800, 600), 0, 32)
    alfhaSurface = DISPLAYSURF.convert_alpha() 
    pygame.display.set_caption('test')
    shipImg = pygame.image.load('ship.png')
    shipImgcpy=shipImg.copy()
    vetShip=pygame.math.Vector2(400,300)
    gradi = 0
    gradiRot=0
    mouseX=0
    mouseY=0
    SHIP_W=40
    SHIP_H=40
    vetMouse=pygame.math.Vector2(mouseX,mouseY)
    #main loop
    while True:
        DISPLAYSURF.fill((0,0,0)) 
        alfhaSurface.fill((0,0,0))
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()  
            if event.type == MOUSEBUTTONDOWN:
                mouseX, mouseY = pygame.mouse.get_pos()
                vetMouse=pygame.math.Vector2(mouseX,mouseY)

                gradiRot=**math.atan2(vetShip.x-vetMouse.x, vetShip.y-vetMouse.y)**
                gradiRot=**math.degrees(gradiRot)**
                pygame.display.set_caption(""+str(gradi) +"="+ str(gradiRot)+" "+ str(vetMouse.angle_to(vetShip)) ) 
        pygame.draw.line(alfhaSurface, (255,255,255), (vetShip.x+SHIP_W,vetShip.y+SHIP_H),(vetMouse.x,vetMouse.y),1)                      
        if gradi != int(gradiRot) :
            if gradiRot > gradi and gradi != gradiRot :
                gradi=gradi+1

            if gradiRot < gradi and gradi != gradiRot :
                gradi=gradi-1    

            shipImgcpy=pygame.transform.rotate(shipImg.copy(),gradi) 

        elif int(vetMouse.distance_to(vetShip)) >0:
            posNext=Move(mouseX,mouseY,vetShip.x+SHIP_W,vetShip.y+SHIP_H,1)                  
          vetShip=pygame.math.Vector2(vetShip.x+posNext[0],vetShip.y+posNext[1])


        alfhaSurface.blit(shipImgcpy, tuple(vetShip))
        DISPLAYSURF.blit(alfhaSurface,(0,0))
        pygame.display.update()
        fpsClock.tick(FPS)   

答案 3 :(得分: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)

答案 4 :(得分:-1)

if event.type == MOUSEBUTTONDOWN:
    mouseX, mouseY = pygame.mouse.get_pos()
    vetMouse=pygame.math.Vector2(mouseX,mouseY)
    gradiRot=vetMouse.angle_to(vetShip)