lover-fish
  • Introduction
  • 搭建环境
  • 绘制背景
  • 绘制海葵
  • 绘制果实
  • 果实动画
  • 控制果实的数量
  • 增加果实的类型
  • 绘制鱼
  • 让鱼动起来
  • 让鱼跟着鼠标动起来
  • 吃果实之碰撞检测
  • 创建鱼宝宝
  • 给鱼添加动画
  • 加入计分模块
  • 大鱼身体特效
  • 游戏结束逻辑
  • 增加吃果实特效
  • 海葵动画
  • 漂浮物
Powered by GitBook
On this page

吃果实之碰撞检测

实现碰撞检测的原理就是每一帧都检测果实和鱼的距离,当距离小于一定值的时候就让果实死亡。

计算坐标轴上面俩个点的距离,大家应该记得,利用了勾三股四原理,不记得百度一下就会立即想起了。

首先我们准备一个计算距离的函数,把它放在 utils.ts 文件里面

interface Pointer{
  x: number,
  y: number
}

/**
 * 计算俩个点的距离
 * @param {Pointer} p1 坐标点
 * @param {Pointer} p2 坐标点
 * @returns 距离的平方根
 */
function getDistance(p1: Pointer, p2: Pointer) {
  return Math.pow((p1.x - p2.x) , 2) + Math.pow((p1.y - p2.y), 2)
}

别忘记导出这个函数

所有需要实时监测的、动画相关的,我们都需要写到循环里面去,在 game-loop.ts 文件里面准备我们的碰撞检测函数。

/**
 * 鱼妈妈与果实的碰撞检测
 */
function fishAndFruitsCollision() {
  for (let i = fruits.num; i >= 0; i--) {
    // 假如或者就计算鱼儿与果实的距离
    if(fruits.alive[i]) {
      // 得到距离的平方根
      const distance = utils.getDistance(
        {x: fruits.x[i], y: fruits.y[i]}, 
        {x: fish_mother.x, y: fish_mother.y}
      );

      // 假如距离小于 700 让它死亡
      if(distance < 700) {
        fruits.dead(i)
      }
    }
  }
}

碰撞之后要死亡,尽管我们可以直接在函数里面改,但是为了封装性,我们还是在 fruits.ts 里面增加一个 dead 函数

  // 果实死亡
  dead(i){
    this.alive[i] = false;
  }

并在 game-loop 的循环里面添加这个函数

function gameLoop() {
  const now = Date.now()
  deltaTime = now - lastTime;
  lastTime = now;

  drawBackbround()  // 画背景图片

  anemones.draw()  // 海葵绘制
  fruits.draw()  // 果实绘制
  fruits.monitor() // 监视果实,让死去的果实得到新生

  ctx_one.clearRect(0, 0, cvs_width, cvs_width); // 清除掉所有,再进行绘制,要不然的话会多次绘制而进行重叠。
  fish_mother.draw() // 绘制鱼妈妈
  fishAndFruitsCollision() // 每一帧都进行碰撞检测
  requestAnimationFrame(gameLoop); // 不断的循环 gameLoop,且流畅性提升
}

此时我们的与应该可以吃果实了。

此时我们再优化一下细节,在 game-loop 给 deltaTime 设置一个上线值,避免切换到其他 tag 的时候,暂停渲染,导致俩次渲染的间隔很大,导致果子巨大失真。

function gameLoop() {
  const now = Date.now()
  deltaTime = now - lastTime;
  lastTime = now;

  if(deltaTime > 40) deltaTime = 40;

  // console.log(deltaTime);

  drawBackbround()  // 画背景图片

  anemones.draw()  // 海葵绘制
  fruits.draw()  // 果实绘制
  fruits.monitor() // 监视果实,让死去的果实得到新生

  ctx_one.clearRect(0, 0, cvs_width, cvs_width); // 清除掉所有,再进行绘制,要不然的话会多次绘制而进行重叠。
  fish_mother.draw() // 绘制鱼妈妈
  fishAndFruitsCollision() // 每一帧都进行碰撞检测
  requestAnimationFrame(gameLoop); // 不断的循环 gameLoop,且流畅性提升
}

同时我们此时测试的时候,现在的鱼儿动起来仿佛搭载了核能发动机一样,跑的飞快,且还能横向移动,减小一下我们的趋向百分率来避免这个问题。同时增加鱼妈妈的体型。

所以我们需要修改下 fish-mother.ts

    this.x = utils.lerpDistance(mouse_x, this.x , .95)
    this.y = utils.lerpDistance(mouse_y, this.y , .95)
    // ....
    ctx_one.scale(.8, .8);
Previous让鱼跟着鼠标动起来Next创建鱼宝宝

Last updated 7 years ago