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

2024-09-28 22:24:39 发布

您现在位置:Python中文网/ 问答频道 /正文

所以,嘿,我对制作游戏和编程都是新手,我试着在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时,它们也会被相加。在

结果,我得到了像这样的子弹Image of the bug

我用我标记的屏幕四分之一的数字在init中的if语句中使用。在

你看,有点不管用。我要子弹打个圈。我该怎么办。在

我承认,我不懂三角法。我在学校还没学过,一年后就会有了。因此,我希望有人尽可能简单地向我解释。告诉我一个更好的方法来代替使用这个硬币。在


Tags: andposselfmoveinitstartendrel
2条回答

好吧。我自己找到了解决办法。在第2和第3季度,子弹仍然不完全指向光标,但它形成了一个圆圈。在

事实证明,我有sin()和cos()函数是有问题的。我只是把它们取下来让代码

self.angle_x = (self.rel_x / self.d) * move_speed
self.angle_y = (self.rel_y / self.d) * move_speed

它现在起作用了。我也可以删除这个季度检测的东西,它现在没有它工作。最终代码如下:

^{pr2}$

结果如下:
A nice circle that looks okay.

不过,有人应该发布一个更好的答案,也解决了子弹不能完全进入鼠标点击位置的问题。在

恭喜你!你已经为自己发现了罪恶和罪恶。在

拿出一张纸,标记两个点:一个是光标位置(=目标),另一个是子弹的电流(起始?)位置。在

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

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

然后画一条垂直线来完成一个三角形,这个三角形的长度是你的相对长度(或“dy”)。在

我不知道你为什么要用到你称之为“角度”和“角度”的变量。一旦发射,角度总是一样的,就像子弹一样(除非目标在移动,而且你在飞行一条追击航线,就像一枚寻的导弹;要进行“纯追击”,你只需每转重新计算航向,所以它总是指向目标的位置)。在

下一步你要做的就是移动多远。这将是d的一部分。如果你的速度大于d,你覆盖了d的全部,然后到达;否则你只覆盖了d的一小部分。所以你想要的是:

if(speed>;d):_d的分数_=1 其他:分数_d=速度/天

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

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

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

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

-史蒂夫

相关问题 更多 >