pygame 矢量的加减乘除

1,302 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情

单位向量

向量实际上描述了两件事:大小和方向。例如,士兵Alpha可以使用矢量AB来计算他必须行进的距离(大小),但矢量也会告诉他面对哪个方向(方向)。通常这两件

信息在向量中捆绑在一起,但有时您只需要一个或另一个。我们已经看到了如何计算幅度,但我们也可以通过将分量除以幅度来从矢量中删除幅度信息。这称为归一化向量,并生成一种称为单位向量的特殊向量。单位向量的长度始终为 1,通常用于表示标题。当我们进入第三维度时,您会发现它们对于从碰撞检测到照明的所有操作都是必不可少的。让我们向 Vector2 添加一个方法,该方法对向量进行归一化并将其转换为单位向量(参见清单 5-9)。

image.png

image.png

执行此脚本将生成以下输出:

image.png

矢量加法

向量加法将两个向量组合在一起,以生成具有两者组合效应的单个向量。假设士兵阿尔法在捡起B点的机器人守卫后,必须与C点(15,45)的降落船会合。从 B 到 C 的向量是 (-15, 10),这意味着他必须在 x 方向上返回 15 个单位,并在 y 方向上继续 5 个单位。如果我们将 BC 向量的分量添加到 AB 向量中,我们得到一个将我们从 A 带到 C 的向量(参见图 5-3)。

image.png

要将向量加法添加到我们的向量库中,我们可以创建一个名为 add 的方法,然后调用 AB.add(BC) 以返回将 AB 和 BC 相加的结果,但如果我们可以简单地调用 AB+BC,那就更自然了。Python为我们提供了一种方法来做到这一点。通过定义一个名为 add 的特殊方法,我们可以让 Python 知道如何将 Vector2 的两个实例相加。当 Python 看到 AB+BC 时,它将尝试调用 AB.add_(BC),因此我们应该定义__add_to返回一个包含计算结果的新对象。这称为运算符重载。所有基本运算符都有类似的特殊方法,例如as__sub_for减去(-)and_mul对于乘法 (*)。清单 5-10 使用加方法。

警告 如果使用列表或元组来存储向量,请不要尝试将它们与 + 运算符一起添加。在蟒蛇 (1, 2)+(3, 4) 不是 (4, 6);它实际上是(1,2,3,4)-这不是一个有效的2D向量。

image.png

image.png

运行结果:

image.png

矢量减法

减去一个向量意味着向向量指向的相反方向前进。如果士兵阿尔法被迫从装备精良的机器人中撤退,他可能会计算出一个指向对手的矢量,然后从他目前的位置减去它,找到他身后的一个点。向量减法的数学运算与加法非常相似,但我们从分量中减去而不是加法。清单 5-11 显示了一个从另一个向量中减去一个向量的方法,您可以将其添加到 Vector2 类中。请注意,与典型方法不同,此方法具有双下划线,就像您所看到的_init__methods一样。由于我们已经创建了我们自己的对象类型,Python不知道什么样的对象。

它可能具有也可能没有的属性。因此,对于python来说,要像我们希望的那样对待减法符号之类的符号,我们需要添加处理这些操作的方法。

如果不添加这些方法,您将在Python中收到一个错误,显示类型错误:不支持的操作数类型-:“矢量2”和“矢量2”

清单 5-11.向量减法方法定义

image.png

向量否定

假设士兵阿尔法到达B点,却发现他忘记了备用电池;他怎么能计算出一个向量回到A(即向量BA)?他可以再次给出这些点进行数学运算,但另一种方法是否定已经计算的向量AB。否定向量将创建指向相反方向的相同长度的向量。因此,-AB 与 BA 相同。要否定向量,只需否定分量即可。清单 5-12 是一个执行否定的成员函数,您可以将其添加到 Vector2 类中。 image.png

向量乘法和除法

也可以将向量乘以(或除以)标量(数字),这具有改变向量长度的效果。只需将每个分量乘以标量值或除以即可。清单 5-13 向 Vector2 类添加了两个方法来实现乘法和除法功能。

image.png

如果将任何向量乘以 2.0,它的大小将加倍;如果将向量除以 2.0(或乘以 0.5),则大小将减半。将向量乘以大于 0 的数字将导致指向相同方向的向量,但如果将生成的向量乘以小于 0 的数字,则生成的向量将被“翻转”并指向相反的方向(参见图 5-4)。

image.png

注意 也可以将一个向量乘以另一个向量,但它在游戏中并不经常使用,您可能永远不会需要它。

那么,士兵阿尔法会如何使用向量乘法——或者更准确地说,游戏程序员会如何使用它呢?矢量乘法可用于根据时间将矢量分解为更小的步骤。如果我们知道 Alpha 可以在 10 秒内覆盖从 A 到 B 的距离,那么我们可以通过使用一点矢量代码来计算 Alpha 每秒之后的坐标。清单 5-14 显示了如何使用 Vector2 类执行此操作。

image.png

在计算了点 A 和点 B 之间的向量之后,清单 5-14 创建了一个向量步长,它是 AB 向量的十分之一。循环中的代码将此值添加到位置,这是我们将用于存储 Alpha 当前位置的另一个向量。我们这样做十次,在Alpha旅程的每一秒一次,打印出当前的位置向量。最终,经过十次迭代,我们到达了B点,安全无恙!如果您要获取输出并绘制点,您会发现它们形成了从A到B的完美直线。

在两点之间移动时,像这样计算中间位置至关重要。您还可以使用矢量来计算重力、外力和摩擦力下的运动,以创建各种逼真的运动。

使用矢量创建运动

现在我们已经介绍了矢量,我们可以使用它们以各种方式移动游戏角色,并实现简单的、基于力的物理特性,使游戏更具说服力。