VUE+Canvas实现雷霆战机打字类小游戏

本文介绍了使用Vue和Canvas实现一个雷霆战机打字游戏的过程,包括固定在底部的飞机、随机出现的单词敌人、追踪敌人的子弹以及游戏结束后的得分展示。通过分析游戏组件和运动逻辑,逐步构建了游戏的基本功能。
摘要由CSDN通过智能技术生成

是的,又是我,在折腾小游戏的路上流连忘返了,之前用vue+canvas实现了一系列简单的小游戏,感兴趣的小伙伴可以戳戳以往的几个帖子:

《VUE实现一个Flappy Bird~~~》

《VUE+Canvas实现上吊火柴人猜单词游戏》

《VUE+Canvas 实现桌面弹球消砖块小游戏》

今天就来实现一个雷霆战机打字游戏,玩法很简单,每一个“敌人”都是一些英文单词,键盘正确打出单词的字母,飞机就会发射一个个子弹消灭“敌人”,每次需要击毙当前“敌人”后才能击毙下一个,一个比手速和单词熟练度的游戏。

首先来看看最终效果图:

emmmmmmmmmmmmm,界面UI做的很简单,先实现基本功能,再考虑高大上的UI吧。

首先依旧是来分析界面组成:

(1)固定在画面底部中间的飞机;

(2)从画面上方随机产生的敌人(单词);

(3)从飞机头部发射出去,直奔敌人而去的子弹;

(4)游戏结束后的分数显示。

这次的游戏和之前的比,运动的部分貌似更多且更复杂了。在flappy bird中,虽然管道是运动的,但是小鸟的x坐标和管道的间隔、宽度始终不变,比较容易计算边界;在弹球消砖块游戏中,木板和砖块都是相对简单或者固定的坐标,只用判定弹球的边界和砖块的触碰面积就行。在雷霆战机消单词游戏中,无论是降落的目标单词,还是飞出去的子弹,都有着各自的运动轨迹,但是子弹又要追寻着目标而去,所以存在着一个实时计算轨道的操作。

万丈高楼平地起,说了那么多,那就从最简单的开始着手吧!

1、固定在画面底部中间的飞机

这个很简单没啥好说的,这里默认飞机宽度高度为40像素单位,然后将飞机画在画面的底部中间:

drawPlane() {
      let _this = this;
      _this.ctx.save();
      _this.ctx.drawImage(
        _this.planeImg,
        _this.clientWidth / 2 - 20,
        _this.clientHeight - 20 - 40,
        40,
        40
      );
      _this.ctx.restore();
},

2、从画面上方随机产生的敌人

这里默认设置每次在画面中最多只出现3个单词靶子,靶子的y轴移动速度为1.3,靶子的半径大小为10:

const _MAX_TARGET = 3; // 画面中一次最多出现的目标

const _TARGET_CONFIG = {

  // 靶子的固定参数

  speed: 1.3,

  radius: 10

};

然后我们一开始要随机在词库数组里取出_MAX_TARGET个不重复的单词,并把剩下的词放进循环词库this.wordsPool中去:

generateWord(number) {
      // 从池子里随机挑选一个词,不与已显示的词重复
      let arr = [];
      for (let i = 0; i < number; i++) {
        let random = Math.floor(Math.random() * this.wordsPool.length);
        arr.push(this.wordsPool[random]);
        this.wordsPool.splice(random, 1);
      }
      return arr;
},
generateTarget() {
      // 随机生成目标
      let _this = this;
      let length = _this.targetArr.length;
      if (length < _MAX_TARGET) {
        let txtArr = _this.generateWord(_MAX_TARGET - length);
        for (let i = 0; i < _MAX_TARGET - length; i++) {
          _this.targetArr.push({
            x: _this.getRandomInt(
              _TARGET_CONFIG.radius,
              _this.clientWidth - _TARGET_CONFIG.radius
            ),
            y: _TARGET_CONFIG.radius * 2,
            txt: txtArr[i],
            typeIndex: -1,
            hitIndex: -1,
            dx: (_TARGET_CONFIG.speed * Math.random().toFixed(1)) / 2,
            dy: _TARGET_CONFIG.speed * Math.random().toFixed(1),
            rotate: 0
          });
        }
      }
}

可以看出,this.targetArr是存放目标对象的数组:

一个初始的目标有随机分布在画面宽度的x;

y轴值为直径;

txt记录靶子代表的单词;

typeIndex记录“轰炸”这个单词时正在敲击的字符索引下标(用来分离已敲击字符和未敲击字符);

hitIndex记录“轰炸”这个单词时子弹轰炸的索引下标(因为子弹真正轰炸掉目标是在打完单词之后,毕竟子弹有飞行时间,所以通过hitIndex来判断子弹什么时候被击碎消失);

dx是靶子每帧在x轴偏移距离;

dy是靶子每帧在y轴偏移距离;

rotate设置靶子自转角度。

好了,生成了3个靶子,我们就让靶子先从上往下动起来吧:

drawTarget() {
      // 逐帧画目标
      let _this = this;
      _this.targetArr.forEach((item, index) => {
        _this.ctx.save();
        _this.ctx.translate(item.x, item.y); //设置旋转的中心点
        _this.ctx.beginPath();
        _this.ctx.font = "14px Arial";
        if (
          index === _this.currentIndex ||
          item.typeIndex === item.txt.length - 1
        ) {
          _this.drawText(
            item.txt.substring(0, item.typeIndex + 1),
            -item.txt.length * 3,
            _TARGET_CONFIG.radius * 2,
            "gray"
      
  • 16
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值