小鸟 Bird

实现思路:

  • 小鸟同样也是继承 矩形类Rectangle,但是小鸟有一些不一样的地方

  • 小鸟需要特别设置的一些属性

    • 小鸟是自然下坠的,所以小鸟需要一个往下的加速度,用g来表示这个属性

    • 小鸟可以往上飞,所以小鸟可以有一个向上的速度,但是这个煽动的动作是要和用户操作绑定的

    • 小鸟的翅膀是可以煽动的,用swing来表示小鸟翅膀的状态

    • 翅膀煽动,单独开启一个计时器,用timer来表示小鸟翅膀煽动的计时器

    • 小鸟不能飞出游戏区域,往上不能低于 0,往下不能低于地面,所以需要算出最低高度maxY

    • 还需要提供一个方法,判断小鸟是否碰到地面,碰到地面自然 GameOver 了

    • 小鸟的render需要重写,因为翅膀的状态在不停的变更

实现代码

点击 展开/收起 jsx 代码
/**
 * @description 小鸟类
 */

import Rectangle from './Rectangle';

class Bird extends Rectangle {
  constructor(birdDom) {
    const birdStyle = getComputedStyle(birdDom);
    const birdWidth = parseFloat(birdStyle.width);
    const birdHeight = parseFloat(birdStyle.height);
    const birdLeft = parseFloat(birdStyle.left);
    const birdTop = parseFloat(birdStyle.top);
    super(birdWidth, birdHeight, birdLeft, birdTop, 0, -10, birdDom);
    this.g = 1000; // 想下单加速度  px/s^2
    // 游戏面板的高度
    const gameHight = document.querySelector('.game').clientHeight;
    // 大地的高度
    const groundHeight = document.querySelector('.ground').clientHeight;
    this.maxY = gameHight - groundHeight - birdHeight;
    // 小鸟翅膀状态
    this.swing = 3;
    this.timer = null;
  }

  startSwing() {
    if (this.timer) {
      return;
    }
    this.timer = setInterval(() => {
      this.swing++;
      if (this.swing === 4) {
        this.swing = 1;
      }
      this.render();
    }, 160);
  }

  stopSwing() {
    clearInterval(this.timer);
    this.timer = null;
  }

  onMove() {
    if (this.top < 0) {
      this.top = 0;
    } else if (this.top > this.maxY) {
      this.top = this.maxY;
    }
  }

  move(duration) {
    super.move(duration);
    // 按照加速度掉落
    const ySpeed = this.ySpeed + this.g * duration;
    this.ySpeed = ySpeed;
    if (this.onMove) {
      this.onMove();
    }
    this.render();
  }

  jump() {
    this.ySpeed = -300;
  }

  // 检查小鸟是否碰到地面
  isHitGround() {
    return this.top >= this.maxY;
  }

  render() {
    super.render();
    this.dom.className = `bird swing${this.swing}`;
  }
}

export default Bird;