Python 在Pygame中如何使子弹正确地朝向光标

Python 在Pygame中如何使子弹正确地朝向光标,python,math,pygame,Python,Math,Pygame,所以,嘿,我对制作游戏和编程都是新手,我试着用Pygame制作一个小游戏,包括一个射击子弹之类的东西。然而,我不能真正正确地掌握射击技巧。我有这样的代码 class Projectile(): def __init__(self, surface, color, start_pos, end_pos, move_speed): super().__init__() # Shooter and target positions self.s

所以,嘿,我对制作游戏和编程都是新手,我试着用Pygame制作一个小游戏,包括一个射击子弹之类的东西。然而,我不能真正正确地掌握射击技巧。我有这样的代码

class Projectile():
    def __init__(self, surface, color, start_pos, end_pos, move_speed):
        super().__init__()

        # Shooter and target positions
        self.start_pos = start_pos
        self.end_pos = end_pos

        # Trigonometry stuffs and like
        self.dx = self.end_pos[0] - self.start_pos[0]
        self.dy = self.end_pos[1] - self.start_pos[1]
        self.rads = atan2(-self.dy,self.dx)
        self.rads %= 2*pi
        self.degs = degrees(self.rads)

        # More stuff I dont understand but it works nearly well.
        self.quarter = self.get_quarter(self.degs)
        # Change the way rel_x and rel_y are calculated so stuff works fair enough
        if self.quarter == 1:
            self.rel_x = -self.end_pos[0] + self.start_pos[0]
            self.rel_y = -self.end_pos[1] + self.start_pos[1]
        elif self.quarter == 2:
            self.rel_x = self.end_pos[0] - self.start_pos[0]
            self.rel_y = -self.end_pos[1] + self.start_pos[1]
        elif self.quarter == 3:
            self.rel_x = -self.end_pos[0] + self.start_pos[0]
            self.rel_y = self.end_pos[1] - self.start_pos[1]
        elif self.quarter == 4:
            self.rel_x = self.end_pos[0] - self.start_pos[0]
            self.rel_y = self.end_pos[1] - self.start_pos[1]

        self.d = (self.rel_x**2 + self.rel_y**2)**0.5
        self.angle_x = ((self.rel_x * cos(self.rads)) / self.d) * move_speed
        self.angle_y = ((self.rel_y * -sin(self.rads)) / self.d) * move_speed

    def move(self):
        self.leftover_x += self.angle_x
        self.leftover_y += self.angle_y
        self.rect.x += int(self.leftover_x)
        self.rect.y += int(self.leftover_y)
        self.leftover_x = (self.leftover_x % 1)
        self.leftover_y = (self.leftover_y % 1)
Move是这样写的,因为Pygame不允许你移动1.337像素,所以我移动1,然后保存.337,当保存的数字的结尾超过1时,它们也会被添加

结果,我得到了类似这样的子弹

我在屏幕上标记了四分之一的数字,这些数字在init中的if语句中使用

你可以看到,有点不起作用。我要子弹围成一个圈。我该怎么办


我承认,我不懂三角学。我在学校还没学过,一年后就会有了。因此,我希望有人尽可能简单地向我解释。告诉我一个更好的方法,让它继续运行,而不是使用这个25美分的东西。

好的。我自己找到了解决办法。在第2节和第3节中,子弹仍然有点不准确地指向光标,但它形成了一个圆圈

事实证明,我有sin()和cos()函数,这就是问题所在。我只是删除了它们,以使代码

self.angle_x = (self.rel_x / self.d) * move_speed
self.angle_y = (self.rel_y / self.d) * move_speed
现在它可以工作了。我也可以删除这个季度检测的东西,它现在没有它的工作。最终代码如下所示:

class Projectile():
    def __init__(self, surface, color, start_pos, end_pos, move_speed):
        super().__init__()

        # Shooter and target positions
        self.start_pos = start_pos
        self.end_pos = end_pos

        # Trigonometry stuffs and like
        # NOW REDUNDANT
        # self.dx = self.end_pos[0] - self.start_pos[0]
        # self.dy = self.end_pos[1] - self.start_pos[1]
        # self.rads = atan2(-self.dy,self.dx)
        # self.rads %= 2*pi
        # self.degs = degrees(self.rads)

        # More stuff I dont understand but it works nearly well.
        # self.quarter = self.get_quarter(self.degs)
        self.rel_x = self.end_pos[0] - self.start_pos[0]
        self.rel_y = self.end_pos[1] - self.start_pos[1]

        self.d = (self.rel_x**2 + self.rel_y**2)**0.5
        self.angle_x = (self.rel_x / self.d) * move_speed
        self.angle_y = (self.rel_y) / self.d) * move_speed
结果如下:


尽管如此,还是应该有人发布一个更好的答案,以解决子弹没有准确到达鼠标点击位置的问题。

好的。我自己找到了解决办法。在第2节和第3节中,子弹仍然有点不准确地指向光标,但它形成了一个圆圈

事实证明,我有sin()和cos()函数,这就是问题所在。我只是删除了它们,以使代码

self.angle_x = (self.rel_x / self.d) * move_speed
self.angle_y = (self.rel_y / self.d) * move_speed
现在它可以工作了。我也可以删除这个季度检测的东西,它现在没有它的工作。最终代码如下所示:

class Projectile():
    def __init__(self, surface, color, start_pos, end_pos, move_speed):
        super().__init__()

        # Shooter and target positions
        self.start_pos = start_pos
        self.end_pos = end_pos

        # Trigonometry stuffs and like
        # NOW REDUNDANT
        # self.dx = self.end_pos[0] - self.start_pos[0]
        # self.dy = self.end_pos[1] - self.start_pos[1]
        # self.rads = atan2(-self.dy,self.dx)
        # self.rads %= 2*pi
        # self.degs = degrees(self.rads)

        # More stuff I dont understand but it works nearly well.
        # self.quarter = self.get_quarter(self.degs)
        self.rel_x = self.end_pos[0] - self.start_pos[0]
        self.rel_y = self.end_pos[1] - self.start_pos[1]

        self.d = (self.rel_x**2 + self.rel_y**2)**0.5
        self.angle_x = (self.rel_x / self.d) * move_speed
        self.angle_y = (self.rel_y) / self.d) * move_speed
结果如下:


尽管如此,还是应该有人发布一个更好的答案,以解决子弹没有准确到达鼠标点击位置的问题。

祝贺你!你已经为自己发现了罪恶和罪恶

拉出一张纸并标记两个点:一个用于光标位置(=目标),另一个用于项目符号的当前(起始?)位置

现在在他们之间划一条线。该行的长度是代码的.d(我想是距离)

然后从其中一个点画一条水平线,距离足够远,使其正好在另一个点的上方或下方结束。它的长度就是你的rel_x(在微积分中你称之为“dx”)

然后画一条垂直线来完成一个三角形——这个长度就是你的相对长度

我不知道你为什么需要称为angle_x和angle_y的变量。一旦发射,角度将始终保持不变,就像子弹一样(除非目标正在移动,并且你正在飞行一条追踪路线,就像一枚寻的导弹;要进行“纯追踪”,你只需在每一圈重新计算路线,因此它始终指向目标当时所在的位置)

接下来你需要的是移动多远。这将是d的一部分。如果你的速度大于d,你覆盖所有的d并到达;否则,您只覆盖d的一小部分。所以你想要的是:

如果(速度>d):d的分数=1 否则:d的分数=速度/d

现在你需要做的就是注意,如果你要走1/n的路到达目标,你也要走1/n的x和y距离(如果你看不清楚的话,盯着纸看的时间会更长)

但是你已经有了x和y的总距离(rel_x和rel_y)。所以你只需将每一个乘以d的分数,就可以知道沿着这个方向移动了多远。然后根据这些数量更新子弹的位置

您将在trig中了解到sin()只是“对边”(三角形的垂直边)的长度除以斜边(d)的长度。cos()就是“相邻”(水平边)的长度除以斜边的长度。你已经有效地计算了正弦和余弦

希望这能让事情变得更清楚


-史蒂夫

祝贺你!你已经为自己发现了罪恶和罪恶

拉出一张纸并标记两个点:一个用于光标位置(=目标),另一个用于项目符号的当前(起始?)位置

现在在他们之间划一条线。该行的长度是代码的.d(我想是距离)

然后从其中一个点画一条水平线,距离足够远,使其正好在另一个点的上方或下方结束。它的长度就是你的rel_x(在微积分中你称之为“dx”)

然后画一条垂直线来完成一个三角形——这个长度就是你的相对长度

我不知道你为什么需要称为angle_x和angle_y的变量。一旦发射,角度将始终保持不变,就像子弹一样(除非目标正在移动,并且你正在飞行一条追踪路线,就像一枚寻的导弹;要进行“纯追踪”,你只需在每一圈重新计算路线,因此它始终指向目标当时所在的位置)

接下来你需要的是移动多远。这将是d的一部分。如果你的速度大于d,你覆盖所有的d并到达;否则,您只覆盖d的一小部分。所以你想要的是:

如果(速度>d):d的分数=1 否则:d的分数=速度/d

现在你需要做的就是注意,如果你要走1/n的路到达目标,你也要走1/n的x和y距离(如果你看不清楚的话,盯着纸看的时间会更长)

但是你已经有了x和y的总距离(rel_x和rel_y)。所以你只需将每一个乘以d的分数,就可以知道沿着这个方向移动了多远。然后根据这些数量更新子弹的位置

你将在tr中学习