Я пытаюсь заставить спрайт двигаться прямо к мышке, используя угол между ними. Этот угол находится с помощью функции atan2
. Хотя этот угол отлично работает для вращения спрайта в направлении мыши, спрайт перемещается в неправильных направлениях в зависимости от квадранта данного угла. Иногда он будет зависать в одном квадранте или двигаться прямо напротив мыши.
Я использую базовые функции Trig
, чтобы найти угол и вычислить правильные добавления к переменным X и Y спрайта. Также важно отметить, что угол, который я вычисляю, хотя он не работает для движения, отлично работает для вращения. Странно, что я пропускаю X-разность между двумя точками, а затем Y-разность, которая противоположна тому, как предполагается обрабатывать обратную касательную функцию. Поэтому я даже не уверен, как этот угол заставляет вращение работать правильно.
Я попытался передать разницу Y и X (в этом порядке) в функцию atan2
. Однако это приводит к неправильному повороту моего спрайта, что наводит меня на мысль о том, что угол в целом также неверен. Я также попытался следовать наряду с многочисленными другими программами, которые используют те же формулы, что и я. Однако они не работают, даже когда я изменяю порядок аргументов на функцию atan2
, чтобы соответствовать программам примера.
def main():
ExitLoop = False
image = IMAGELOADER.AllImages["Fighter1"]
image2 = IMAGELOADER.AllImages["Fighter2"]
Fighter1 = FighterClass.Fighter(image,(700,700))
Fighter2 = FighterClass.Fighter(image2,(300,300))
while not ExitLoop:
ScreenController.Refresh()
mouse_pos = pygame.mouse.get_pos()
Fighter2.set_x(mouse_pos[0]-32)
Fighter2.set_y(mouse_pos[1]-32)
angle = math.atan2(Fighter1.get_x()-mouse_pos[0]+32, Fighter1.get_y()-mouse_pos[1]+32)
degrees_angle = math.degrees(angle)
Fighter1.rotate(degrees_angle)
xval = Fighter1.get_x()
yval = Fighter1.get_y()
speed = Fighter1.get_speed()
changex = (speed*math.cos(angle))
changey = (speed*math.sin(angle))
Fighter1.set_x(xval+changex)
Fighter1.set_y(yval+changey)
for event in pygame.event.get():
if event.type == pygame.QUIT:
ExitLoop = True
ScreenController.Draw(Fighter1.get_image(),Fighter1.get_rect(),False)
ScreenController.Draw(Fighter2.get_image(),Fighter2.get_rect(),False)
ScreenController.DisplayUpdate()
clock.tick(60)
Код класса (относится к классу бойцов)
import pygame
import WoodysFunctions
class Fighter(pygame.sprite.Sprite):
def __init__(self,image,XnY):
pygame.sprite.Sprite.__init__(self)
self.image = image
self.__image_source = image
self.rect = self.image.get_rect()
self.__mask = pygame.mask.from_surface(self.image)
self.rect.x = XnY[0]
self.rect.y = XnY[1]
self.__speed = 1
def get_image(self):
return self.image
def get_rect(self):
return self.rect
def get_mask(self):
return self.__mask
def get_x(self):
return self.rect.x
def get_y(self):
return self.rect.y
def get_speed(self):
return self.__speed
def set_image(self,value):
self.image = value
def set_rect(self,value):
self.__rect = value
def set_mask(self,value):
self.__mask = value
def set_x(self,value):
self.rect.x = value
def set_y(self,value):
self.rect.y = value
def set_speed(self,value):
self.__speed = value
def rotate(self,angle):
old_center = self.rect.center
self.image = pygame.transform.rotate(self.__image_source,angle)
self.rect = self.image.get_rect()
self.rect.center = old_center
Ожидаемый результат: Sprite движется прямо к мыши
Фактическое поведение: спрайт движется в неправильных направлениях, при этом поведение демонстрирует закономерности, зависящие от квадранта расчетного угла.
Edit:
Я изменил программу так, чтобы переменные X и Y спрайта сохранялись в переменных, отличных от объекта rect Это предотвращает десятичное усечение. Я также пересчитал угол между спрайтом и указателем мыши после завершения кода поворота. При пересчете разностные параметры X и Y меняются местами, чтобы соответствовать обратной функции тангенса вместо обратной функции котангенса. Этот пересчитанный угол используется для углового перемещения, а первый угол с разницей X, пройденной первым, используется для вращения. Важно отметить, что после того, как я вычислил переменные changeX и changeY, используя пересчитанный угол (с переданной разницей Y), я умножил их на -1, так как в противном случае спрайт отойдет от указателя мыши.