Таким образом, Мумии объекта необходимо следовать объекту Player.Уточнение этого описания проблемы далее:
Каждый раз, когда Мумия движется, она должна быть в направлении Игрока.
Так как же мысделать это?
Представьте, что мы рисуем стрелку из положения мумии к игроку.Это определит направление, в котором должна двигаться мама.В формальных (математических) терминах это направление вектор .Чтобы определить вектор направления, мы прорабатываем линию между двумя точками, затем нормализуем , разделив ее на длину.
В результате получаем простую x
иy
единичный вектор , составляющие которого можно умножить на скорость объекта, чтобы получить его следующую позицию.
В приведенном ниже примере есть 3 спрайта, которые будут перемещаться в направлении положения мыши.Важной частью является функция MySprite.update()
.Это захватывает положение мыши (в вашем случае это игрок) и местоположение спрайта (положение мумии), используя эти две точки для вычисления вектора.Как только вектор определен, компоненты используются вместе со скоростью спрайта для вычисления следующей позиции.Я сохраняю позицию внутри как поплавок, так что небольшие углы изменения и низкие скорости обрабатываются лучше.
import pygame
import random
import math
# Window size
WINDOW_WIDTH=400
WINDOW_HEIGHT=400
BLACK = (50,50,50)
class MySprite( pygame.sprite.Sprite ):
def __init__( self, filename ):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(filename).convert_alpha()
self.rect = self.image.get_rect()
self.speed = random.randrange( 1, 3 )
self.xfloat = random.randrange( 0, WINDOW_WIDTH )
self.yfloat = random.randrange( 0, WINDOW_HEIGHT )
self.rect.center = ( int( self.xfloat ), int( self.yfloat ) )
def update( self ):
# Re-compute our new movement vector based on the mouse every update
# so we always move towards the mouse
mouse_pos = pygame.mouse.get_pos()
if ( mouse_pos != (0, 0) ):
my_pos = [ self.rect.centerx, self.rect.centery ]
dir_vector= self.normalisedMovementVector( my_pos, mouse_pos )
x_delta = self.speed * dir_vector[0]
y_delta = self.speed * dir_vector[1]
self.xfloat += x_delta
self.yfloat += y_delta
self.rect.center = ( int(self.xfloat), int(self.yfloat) )
def lineLength( self, pointa, pointb ):
""" Return the length of a line between the two points, in pixels """
x1,y1 = pointa
x2,y2 = pointb
# length = sqrt((x2 - x1)^2 + (y2 - y1)^2)
x_squared = (x2 - x1) * (x2 - x1)
y_squared = (y2 - y1) * (y2 - y1)
length = math.sqrt( x_squared + y_squared )
return length
def normalisedMovementVector( self, pointa, pointb ):
""" Return a normalised vector between to points """
# offset it from (0,0) to make calculations simpler
# since it's a *direction* the actual positions don't matter
pointb = (pointb[0]-pointa[0], pointb[1]-pointa[1])
length = self.lineLength( (0,0), pointb )
# normalise it (divide by it's own length)
if ( length > 0 ):
x = pointb[0] / length
y = pointb[1] / length
move_vector = ( x , y )
else:
# catch division by zero
move_vector = ( 0, 0 )
return move_vector
### MAIN
# Initialise the window
pygame.init()
SURFACE_TYPE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
WINDOW = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE_TYPE )
pygame.display.set_caption("Follow Mouse")
# Add some sprites
SPRITES = pygame.sprite.Group()
for i in range(3):
s = MySprite( 'tiny_alien.png' )
SPRITES.add( s ) # Put in sprites group
# tick tick tick
clock = pygame.time.Clock()
# Main loop
done = False
while not done:
# Move the sprites (nd checks for collisions)
SPRITES.update()
# Handle user input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
elif ( event.type == pygame.VIDEORESIZE ):
WINDOW_WIDTH = event.w
WINDOW_HEIGHT = event.h
WINDOW = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE_TYPE )
# Paint the screen
WINDOW.fill( BLACK )
SPRITES.draw( WINDOW )
pygame.display.flip()
clock.tick_busy_loop( 60 )
# Bye
pygame.quit()
Любое изображение PNG можно заменить на tiny_alien.png
.
![follow_mouse.gif](https://i.stack.imgur.com/lGCK1.gif)
(анимированный .gif немного резвый, но на экране он плавный)