ES6飞机大战篇-添加子弹追踪功能

既然是飞机大战 那必定少不了子弹追踪

那么添加子弹追踪功能的实现如下:


// 原文链接:https://blog.youkuaiyun.com/erweimac/article/details/82256087
// https://blog.youkuaiyun.com/weixin_30756499/article/details/97551805
// https://blog.youkuaiyun.com/looffer/article/details/8846159
// https://github.com/processing/p5.js
/**
 * @description: 追踪目标
 * @param {number} x1 追踪目标x轴
 * @param {number} y1 追踪目标y轴
 * @param {number} x2 追踪者x轴
 * @param {number} y2 追踪者y轴
 * @param {number} speed 追踪者速度
 * @return {Object} {x, y} 返回下一次要移动的位置
 */
function FollowUpBullet(x1, y1, x2, y2, speed) {
  // 向量
  const deltaX = x1 - x2;
  const deltaY = y1 - y2;
  // 微小偏移
  if (deltaX == 0) {
    if (y1 >= y2) {
      deltaX = 0.0000001;
    } else {
      deltaX = -0.0000001;
    }
  }
  if (deltaY == 0) {
    if (x1 >= x2) {
      deltaY = 0.0000001;
    } else {
      deltaY = -0.0000001;
    }
  }

  let angle = 0;
  let π = Math.PI;
  // 右下角
  if (deltaX > 0 && deltaY > 0) {
    angle = Math.atan(Math.abs(deltaY / deltaX)); // 第一项限
    // 左下角
  } else if (deltaX < 0 && deltaY > 0) {
    angle = π - Math.atan(Math.abs(deltaY / deltaX)); // 第二项限
    // 左上角
  } else if (deltaX < 0 && deltaY < 0) {
    angle = π + Math.atan(Math.abs(deltaY / deltaX)); // 第三项限
    // 右上角
  } else {
    angle = 2 * π - Math.atan(Math.abs(deltaY / deltaX)); // 第四项限
  }
  let x = speed * Math.cos(angle);
  let y = speed * Math.sin(angle);
  return { x, y, angle: calAngle(x2, y2, x1, y1) };
}
// 参考:https://juejin.cn/post/6844903880493367304
// 计算角度
function calAngle(cx, cy, x, y) {
  const radian = getCosBy2pt(x, y, cx, cy);
  let angle = (Math.acos(radian) * 180) / Math.PI;
  if (x < cx) angle = -angle;
  return angle;
  // 计算 点1指点2形成 的向量
  function getCosBy2pt(x, y, cx, cy) {
    let a = [x - cx, y - cy];
    let b = [0, -1];
    return calCos(a, b);
  }
  function calCos(a, b) {
    // 点积
    let dotProduct = a[0] * b[0] + a[1] * b[1];
    let d =
      Math.sqrt(a[0] * a[0] + a[1] * a[1]) *
      Math.sqrt(b[0] * b[0] + b[1] * b[1]);
    return dotProduct / d;
  }
}

当然做之前肯定百度了一下 既然可以CV就尽量不自己写代码
跟踪代码有了 那么就是实装了

// 跟踪子弹
		// 获取敌机的数据
          const enemyStoreList = enemyStore.getStore();
          const keys = Object.keys(enemyStoreList);
          // 找到第一个幸运儿
          const enemy = enemyStoreList[keys[0]];
          // 如果没有敌机 子弹往前飞
          if (enemy === undefined) {
            // 数据移动
            this.positionY -= this.bulletFlySpeed;
          } else {
          	// 调用子弹追踪
            const { x, y, angle } = FollowUpBullet(
              enemy.positionX + containerInfo.offsetLeft + enemy.width / 2,
              enemy.positionY + containerInfo.offsetTop + enemy.height / 2,
              this.positionX,
              this.positionY,
              this.bulletFlySpeed
            );
            // 保存位置
            this.positionY += y;
            this.positionX += x;
            // 子弹旋转
            this.angle = angle;

那么就有了追踪效果了 方便的很

这只是当中一个方法 完整飞机大战项目可以查看:https://github.com/SDSGK/plane-ES6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值