首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Python/Pygame中寻找具有给定角度的适当X/Y坐标修饰符

在Python/Pygame中寻找具有给定角度的适当X/Y坐标修饰符
EN

Stack Overflow用户
提问于 2019-05-21 10:34:23
回答 1查看 64关注 0票数 3

我试图让一个精灵直接向鼠标移动,利用它们之间的角度。这个角度是通过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)

类代码(与fighter类相关)

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对象的变量中。这可以防止小数截断。在完成旋转代码后,我还重新计算了sprite和鼠标指针之间的角度。在重新计算中,交换X和Y差参数以匹配逆切函数而不是反余切函数。此重新计算的角度用于角度移动,第一个角度用于旋转,其中X差值最先传递。重要的是要注意,在我使用重新计算的角度(首先传递Y差)计算changeX和changeY变量后,我将它们乘以-1,否则精灵将从鼠标指针移开。

EN

回答 1

Stack Overflow用户

发布于 2019-05-21 23:56:08

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

由于您正在处理任何角度和三角函数,因此您将以被截断的浮点数结束:

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

在这里,如果value是1.4,那么self.rect.x就变成了1,所以你失去了“准确性”。

这种精度损失会在主循环(每个帧)的每次迭代中传播,从而导致意外的运动方向。

最好的解决方案是将所有值存储在一个单独的数据结构中,并仅为屏幕中的绘图更新rect属性。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56230371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档