心血来潮:做一个网页游戏,飞机大战

前言

体验地址:https://qflyb.github.io/airplanewar/

飞机大战小游戏主体还是比较简单的,但是看似简单的外壳下面有着很多细节。如果要将细节做到极致,那需要花大量的功夫,我这里只是大体实现了飞机大战。

体验地址

整个游戏是使用cocos实现,先看一下游戏画面截图:

img

这篇文章不准备针对所有代码去讲解,只挑选制作过程中印象比较深的踩坑之处,代码都是用的TypeScript,TypeScript在JavaScript的基础上面加了很多限制,那么为什么还要使用TypeScript?因为TypeScript的类,更像Java,C#这种语言,用着更顺手一些。

飞机的移动

玩家飞机

玩家飞机操控根据上图也能看出来,是依据触摸屏幕的点进行判断,cocos里面提供了一个cc.Node.EventType.TOUCH_MOVE方法,可以在监听玩家手指在屏幕上面滑动。同时还提供了getPreviousLocation可以获取到上一帧手指所在的位置,而getLocation可以获取到当前帧手指所在的位置,然后通过两帧位置的差值,再将飞机的位置减去这个差值,就可以实现飞机的移动。

// 控制
this.node.on(
  cc.Node.EventType.TOUCH_MOVE,
  function (event) {
    if (GameMode.gameOver) {
      return;
    }
    this.player.x -= event.getPreviousLocation().x - event.getLocation().x;
    this.player.y -= event.getPreviousLocation().y - event.getLocation().y;
  },
  this
);

敌方飞机

敌方飞机的生成是使用一个随机数,让它在屏幕外面随机生成,同时不断的改变飞机的y轴值就可以实现一直向下移动。

creatEnemy(enemyCount: number, enemyList: Array<cc.Node>, hp: number) {
  let enemy = enemyList[enemyCount];
  let enemyS: Enemy = enemy.getComponent("Enemy");
  enemyS.death = false;
  enemyS.hp = hp;
  enemy.setPosition(
    Math.floor(Math.random() * 570 - 285), // 位置随机
    this.enemyPos.getPosition().y
  );
  enemy.active = true;
}

动画系统

飞机的爆炸都是通过cocos的动画系统来实现,在飞机判断死亡时,就开始播放动画,等到动画结束,就将敌方飞机的渲染关闭。这里使用的是关闭渲染而不是进行销毁对象,因为对象的动态创建是非常消耗性能的,所以我选择在游戏加载的时候就将敌方的几十架飞机全部创建,然后要使用时对它们进行初始化。

initEnemy(enemyList: Array<cc.Node>, enemy: cc.Node, count: number) {
  //生成敌人
  for (let i = 0; i < count; i++) {
    let ene = cc.instantiate(enemy);
    this.node.addChild(ene);
    ene.active = false;
    enemyList[i] = ene;
  }
}

击中目标

cocos自带了碰撞功能,只需要在初始化时开启碰撞,并且在组件上面添加了碰撞盒子,就可以通过onCollisionEnter方法监听到碰撞。

let manager = cc.director.getCollisionManager();
manager.enabled = true; // 开启碰撞

img

细节部分

重新开始

使用cocos提供的方法cc.director.loadScene("Game");就可以重置场景,但是这里我遇到了一个坑,不管是通过该方法提供的回调函数,还是直接写在下面,重置时都无法再次拿到当前脚本上的对象。

注意

生成不同等级的敌方飞机这是一个非常需要考虑细节的地方。制作游戏的时候你需要考虑再加入一种类型的飞机,那么需要怎么加才最方便,而不是需要加一种敌方飞机,就又重新全部写一次代码。当然,因为偷懒,所以这部分我基本没有怎么考虑了。