编程语言
首页 > 编程语言> > 在Python / Pygame中查找具有给定角度的正确X / Y坐标修改器

在Python / Pygame中查找具有给定角度的正确X / Y坐标修改器

作者:互联网

我试图利用它们之间的角度使精灵直接移向鼠标.可通过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会直接移向鼠标

实际行为:精灵向错误的方向移动,行为显示的图案取决于所计算角度的象限.

编辑:
我更改了程序,以便将精灵的X和Y变量存储在与rect对象分开的变量中.这样可以防止小数位截断.旋转代码完成后,我还重新计算了精灵和鼠标指针之间的角度.在重新计算中,交换X和Y差异参数以匹配反正切函数而不是反正切函数.重新计算的角度用于角度移动,而第一个角度(首先传递X差)用于旋转.重要的是要注意,在使用重新计算的角度(首先传递了Y差)计算了changeX和changeY变量之后,我将它们乘以-1,否则精灵将远离鼠标指针.

解决方法:

我不能百分百确定,但是我认为问题是pygame.Rect将位置存储为整数,因为它应该以像素为单位存储坐标和尺寸,当然不能绘制一半像素.

由于您要处理任何角度和三角函数,因此您在进行以下操作时会截断浮点数:

def set_x(self,value):
    self.rect.x = value

在这里,如果值是1.4,则self.rect.x变为1.因此,您将失去“准确性”.

这种准确性的损失会在主循环(每帧)的每次迭代中传播,从而导致意外的运动方向.

最好的解决方案是将所有值存储在单独的数据结构中,并仅在屏幕上绘制时更新rect属性.

标签:pygame,trigonometry,python
来源: https://codeday.me/bug/20191210/2104596.html