如何将精灵旋转到鼠标并移动它? [英] How do I rotate a sprite towards the mouse and move it?
问题描述
我很困惑,在我的代码中,精灵的坐标似乎没有改变它的位置.放入 (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()
如果你想在鼠标的方向上移动对象,那么你必须添加一个 direction
和 position
类型的属性
导入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, andSprite.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屋!