cocos-awesome/doc/Bullet_Tracking/子弹跟踪效果.md
2022-03-07 09:15:59 +08:00

2.6 KiB
Raw Permalink Blame History

效果演示

打击的目标一直在移动,但是子弹却像长了眼睛一样在后面尾随,直到精准击中目标。这种“长了眼睛的子弹”,是打击类游戏中比较经典的武器之一。

demo

实现思路

首先要排除掉用的动画来实现,因为我们的目标在实时地移动,所以子弹的终点位置是不确定的,同时在移动的时候,我们的子弹的方向也需要进行实时的调整,整个过程中起点和终点不确定,运动过程也不确定,因此整个过程不能用一个动画过程去模拟。

但是我们可以在update的时候去实时改变子弹的方向和处理速度变化。在每帧的回调中,我们可以拿到当前目标的位置和子弹的位置,然后我们通过向量减法,算出子弹到目标的归一化向量,然后再给子弹做位置的叠加和角度的叠加。

detail

这里面涉及到两个向量处理,一个是向量减法,如上图所示,它的意义应该不难理解,就是表达了子弹到目标的这个过程。还有一个处理叫做归一化向量简单点说就是单位长度为1的向量因此也把它叫单位向量或者标准向量对于大部分向量而言我们只关心向量的方向而不在意向量的长度这种情况下就适合用单位向量来表示比如光线的入射方向、反射的方向等当然还有我们这个例子中用到的“跟踪子弹”要实现这个功能我们要做的就是让子弹能够朝目标的方向去运动而运动的步长就是我们自己自定义的速度实现代码如下

bulletSpeed = 200;
update(dt) {
  if (!this.fireFlag) return;

  let targetPos: cc.Vec2 = this.target.getPosition();
  let bulletPos: cc.Vec2 = this.bullet.getPosition();
  let normalizeVec: cc.Vec2 = targetPos.subtract(bulletPos).normalize();

  this.bullet.x += normalizeVec.x * this.bulletSpeed * dt;
  this.bullet.y += normalizeVec.y * this.bulletSpeed * dt;
  // 角度变化以y轴正方向为起点逆时针角度递增
  this.bullet.angle = cc.v2(0, 1).signAngle(normalizeVec) * 180 / Math.PI;

  let rect = this.target.getBoundingBox();
  if (rect.contains(bulletPos)) this.hitTheTarget();
}

因为节点的角度是以y轴正方向为起点逆时针递增所以在计算子弹的角度的时候可以使用cc.v2(0, 1).signAngle(normalizeVec)算出当前向量和y轴夹角的弧度然后再转化成角度赋值。

效果预览

源码获取请点击查看原文,长按二维码查看效果👇

ewm