[英]Finding proper X/Y coordinate modifiers with given angle in Python/Pygame
我正在尝试使用它们之间的角度直接朝向鼠标移动精灵。 该角度通过atan2
函数找到。 虽然这个角度可以很好地将精灵旋转到鼠标,但精灵会根据给定角度的象限向错误的方向移动。 它有时会在一个象限中冻结,或者直接在鼠标对面移动。
我正在使用基本的Trig
函数来查找角度,并计算精灵的X和Y变量的正确添加。 同样重要的是要注意,我计算的角度,虽然它不适用于运动,但它确实适用于旋转。 奇怪的是,我传递了两个点之间的X差异,然后是Y差异,这与应该如何处理反正切函数相反。 因此,我甚至不确定这个角度是如何使旋转正常工作的。
我试图将Y差异和X差异( atan2
顺序)传递给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直接朝向鼠标移动
实际行为:Sprite在错误的方向上移动,行为显示取决于计算角度的象限的模式。
编辑:我更改了程序,以便精灵的X和Y变量存储在与rect对象分开的变量中。 这可以防止十进制截断。 旋转代码完成后,我还重新计算了精灵和鼠标指针之间的角度。 在重新计算中,交换X和Y差分参数以匹配反正切函数而不是反余切函数。 该重新计算的角度用于角度移动,并且第一角度(首先通过X差异)用于旋转。 重要的是要注意,在我使用重新计算的角度(首先传递Y差值)计算changeX和changeY变量后,我将它们乘以-1,否则精灵将远离鼠标指针。
我不能100%肯定,但我认为问题是pygame.Rect
将位置存储为整数,因为它应该以像素为单位存储坐标和尺寸,当然你不能绘制半像素。
由于您正在处理任何角度和三角函数,因此当您执行以下操作时,将以截断的浮点结束:
def set_x(self,value):
self.rect.x = value
在这里,如果value
1.4,则self.rect.x
变为1.因此您将失去“准确性”。
这种精度损失在主循环(每个帧)的每次迭代中传播,导致意外的运动方向。
最佳解决方案是将所有值存储在单独的数据结构中,并仅更新rect
属性以在屏幕中绘制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.