今天拜读徐波老师的《golang从入门到实践》书籍中看到一个小例子,使用golang来实现二维矢量模拟玩家移动。其中介绍在游戏中,一般使用二维矢量保存玩家的位置 。 使用矢量运算计算玩家移动的位置。 觉得很有趣,和大家分享一下。
1 .实现二维矢量结构
二维矢量拥有两个方向的信息 ,同时可以进行加、 减、乘 (缩放)、距离 、 单位化等计算 。我们先使用拥有 X 和 Y 两个分量的 Vec2 结构体实现这个二维矢量(即数学中向量)的概念 。
2 .实现玩家对象
(1) 使用矢量减法,将目标位置( targetPos )减去当前位置( currPos )即可计算出位于两个位置之间的新矢量。
(2)使用 Nonnalize() 方法将方向矢量变为模(长度)为1的单位化矢量。 这里需要将矢量单位化后才能进行后续计算。
(3)获得方向后,将单位化方向矢量根据速度进行等比缩放,速度越快,速度数值越大,乘上方向后生成的矢量就越长(模很大)。
(4) 将缩放后的方向 添加到 当前位置后形成新的位置 。
运行结果:
总结:
首先我们实现一个矢量结构 Vec2 来保存玩家的位置坐标,并为这个结构定义了加、减、乘、单位化方法。使用这一系列矢量运算计算出玩家移动的位置。
然后我们实现一个玩家对象,定义玩家的当前位置 、目标位置和速度属性,为这个对象实现操作她的方法,比如设置目的地,更新位置等来模拟玩家的移动。
在更新玩家位置逻辑中计算当前位置指向目标的朝向时,先将两矢量相减获得指向被减矢量的新矢量。然后将新矢量使用 Normalize()方法单位化 。最终返回的 dir 矢量就是移动方向(因为单位化后模为1)。这个dir矢量和速度属性配合计算玩家移动后的新位置。
在IsArrived方法中判断玩家是否到达目标点。玩家每次移动的半径就是速度( speed ),因此,如果当前位置与目标点的距离小于速度,表示己经非常靠近目标,可以视为到达目标。