如何将精灵旋转到鼠标并移动它? [英] How do I rotate a sprite towards the mouse and move it?

查看:79
本文介绍了如何将精灵旋转到鼠标并移动它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很困惑,在我的代码中,精灵的坐标似乎没有改变它的位置.放入 (200, 200) 与放入 (900, 100000) 相同.所以基本上我无法在指定位置协调精灵.你能帮忙吗?

感谢 Ann Zen但是我身上的精灵问题

导入pygamewn = pygame.display.set_mode((400, 400))时钟 = pygame.time.Clock()类玩家(pygame.sprite.Sprite):def __init__(self, x, y):pygame.sprite.Sprite.__init__(self)self.original_image = pygame.image.load('Sprite0.png')self.image = self.original_imageself.rect = self.image.get_rect(center = (x, y))self.velocity = 5def point_at(self, x, y):方向 = pygame.math.Vector2(x, y) - self.rect.center角度 = direction.angle_to((0, -1))self.image = pygame.transform.rotate(self.original_image, 角度)self.rect = self.image.get_rect(center=self.rect.center)定义移动(自我,x,y):self.rect.move_ip(x * self.velocity, y * self.velocity)玩家 = 玩家(200, 200)all_sprites = pygame.sprite.Group(玩家)为真:时钟滴答(60)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:pygame.quit()player.point_at(*pygame.mouse.get_pos())键 = pygame.key.get_pressed()player.move(keys[pygame.K_d]-keys[pygame.K_a],keys[pygame.K_s]-keys[pygame.K_w])wn.fill((255, 255, 255))all_sprites.draw(wn)pygame.display.update()


如果你想在鼠标的方向上移动对象,那么你必须添加一个 directionposition 类型的属性

导入pygamewn = pygame.display.set_mode((400, 400))时钟 = pygame.time.Clock()类玩家(pygame.sprite.Sprite):def __init__(self, x, y):pygame.sprite.Sprite.__init__(self)self.original_image = pygame.image.load('Sprite0.png')self.image = self.original_imageself.rect = self.image.get_rect(center = (x, y))self.direction = pygame.math.Vector2((0, -1))self.velocity = 5self.position = pygame.math.Vector2(x, y)def point_at(self, x, y):self.direction = pygame.math.Vector2(x, y) - self.rect.center如果 self.direction.length() >0:self.direction = self.direction.normalize()角度 = self.direction.angle_to((0, -1))self.image = pygame.transform.rotate(self.original_image, 角度)self.rect = self.image.get_rect(center=self.rect.center)定义移动(自我,x,y):self.position -= self.direction * y * self.velocityself.position += pygame.math.Vector2(-self.direction.y, self.direction.x) * x * self.velocityself.rect.center = round(self.position.x), round(self.position.y)玩家 = 玩家(200, 200)all_sprites = pygame.sprite.Group(玩家)为真:时钟滴答(60)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:pygame.quit()elif event.type == pygame.MOUSEMOTION:player.point_at(*event.pos)键 = pygame.key.get_pressed()player.move(keys[pygame.K_d]-keys[pygame.K_a],keys[pygame.K_s]-keys[pygame.K_w])wn.fill((255, 255, 255))all_sprites.draw(wn)pygame.display.update()

I'm confused by the fact that in my code the sprite's coordinates don't seem to change where it is. Putting (200, 200) would be the same as putting (900, 100000). So basically i cannot coordinate the sprite in a designated position. Can you help?

Turning credits to Ann Zen But the sprite problems on me Pygame sprite not turning accordingly to mouse

My code:

import pygame
from math import atan2, degrees
# tank = pygame.image.load('Sprite0.png')
wn = pygame.display.set_mode((400, 400))

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('Sprite0.png')
        self.x = 0
        self.y = 0
        self.rect = self.image.get_rect()



    def point_at(self, x, y):
        rotated_image = pygame.transform.rotate(self.image, degrees(atan2(x-self.rect.x, y-self.rect.y)))
        new_rect = rotated_image.get_rect(center=self.rect.center)
        wn.fill((255, 255, 255))
        wn.blit(rotated_image, new_rect.topleft)




player = Player()
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
        elif event.type == pygame.MOUSEMOTION:
            player.point_at(*pygame.mouse.get_pos())

    # wn.blit(tank, Player)
    pygame.display.update()

解决方案

Please read the answer to How to rotate an image(player) to the mouse direction? carefully. The calculation of the angle

degrees(atan2(x-self.rect.x, y-self.rect.y))

works by chance. It works, because atan2(x, y) == atan2(-y, x)-pi/2.

The angle of a vector (x, y) is atan2(y, x). The y-axis needs to be reversed (-y) as the y-axis is generally pointing up, but in the PyGame coordinate system the y-axis is pointing down. Most likely your Sprite points upwards and you want to compute:

angle = degrees(atan2(self.rect.y - y, x - self.rect.x)) - 90

respectively

direction = pygame.math.Vector2(x, y) - self.rect.center
angle = direction.angle_to((0, -1))

See also How to know the angle between two points?


The Sprite is drawn at the location stored in rect attribute. You don't need the x and y attribute at all. Just set the location of the rectangle (rect).
Add x and y arguments to the constructor:

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('Sprite0.png')
        self.rect = self.image.get_rect(center = (x, y))

Add a method move and use pygame.Rect.move_ip to change the position of the Sprite:

class Player(pygame.sprite.Sprite):
    # [...]

    def move(self, x, y):
        self.rect.move_ip(x, y)

Invoke move, when you want to change the position of the Sprite:

keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
    player.move(0, -1)
if keys[pygame.K_s]:
    player.move(0, 1)
if keys[pygame.K_a]:
    player.move(-1, 0)
if keys[pygame.K_d]:
    player.move(1, 0)

respectively

keys = pygame.key.get_pressed()
player.move(keys[pygame.K_d]-keys[pygame.K_a], keys[pygame.K_s]-keys[pygame.K_w])

A Sprite should always be contained in a pygame.sprite.Group. See pygame.sprite.Group.draw():

Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect for the position.

Add a Group and add the Sprite to the Group:

player = Player(200, 200)
all_sprites = pygame.sprite.Group(player)

Invoke draw when you want to draw all the Sprites in the Group:

all_sprites.draw(wn)

Ensure that the rotated image is stored in the image attribute:

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.original_image = pygame.image.load('Sprite0.png')
        self.image = self.original_image
        self.rect = self.image.get_rect(center = (x, y))

    def point_at(self, x, y):
        direction = pygame.math.Vector2(x, y) - self.rect.center
        angle = direction.angle_to((0, -1))
        self.image = pygame.transform.rotate(self.original_image, angle)
        self.rect = self.image.get_rect(center=self.rect.center)

    # [...]


Minimal example:

import pygame
wn = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.original_image = pygame.image.load('Sprite0.png')
        self.image = self.original_image
        self.rect = self.image.get_rect(center = (x, y))
        self.velocity = 5

    def point_at(self, x, y):
        direction = pygame.math.Vector2(x, y) - self.rect.center
        angle = direction.angle_to((0, -1))
        self.image = pygame.transform.rotate(self.original_image, angle)
        self.rect = self.image.get_rect(center=self.rect.center)

    def move(self, x, y):
        self.rect.move_ip(x * self.velocity, y * self.velocity)


player = Player(200, 200)
all_sprites = pygame.sprite.Group(player)

while True:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

    player.point_at(*pygame.mouse.get_pos())
    keys = pygame.key.get_pressed()
    player.move(keys[pygame.K_d]-keys[pygame.K_a], keys[pygame.K_s]-keys[pygame.K_w])

    wn.fill((255, 255, 255))
    all_sprites.draw(wn)
    pygame.display.update()


If you want to move the object in the direction of the mouse, then you have to add a direction and position attribute of type pygame.math.Vecotr2. The direction is changed in point_at and the position is changet in move, dependent on the direction. The rect attribute has to be updated.


Minimal example:

import pygame
wn = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.original_image = pygame.image.load('Sprite0.png')
        self.image = self.original_image
        self.rect = self.image.get_rect(center = (x, y))
        self.direction = pygame.math.Vector2((0, -1))
        self.velocity = 5
        self.position = pygame.math.Vector2(x, y)

    def point_at(self, x, y):
        self.direction = pygame.math.Vector2(x, y) - self.rect.center
        if self.direction.length() > 0:
            self.direction = self.direction.normalize()
        angle = self.direction.angle_to((0, -1))
        self.image = pygame.transform.rotate(self.original_image, angle)
        self.rect = self.image.get_rect(center=self.rect.center)

    def move(self, x, y):
        self.position -= self.direction * y * self.velocity
        self.position += pygame.math.Vector2(-self.direction.y, self.direction.x) * x * self.velocity
        self.rect.center = round(self.position.x), round(self.position.y)


player = Player(200, 200)
all_sprites = pygame.sprite.Group(player)

while True:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
        elif event.type == pygame.MOUSEMOTION:
            player.point_at(*event.pos)

    keys = pygame.key.get_pressed()
    player.move(keys[pygame.K_d]-keys[pygame.K_a], keys[pygame.K_s]-keys[pygame.K_w])

    wn.fill((255, 255, 255))
    all_sprites.draw(wn)
    pygame.display.update()

这篇关于如何将精灵旋转到鼠标并移动它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆