用javascript 面向对象制作坦克大战(四)

页面导航:首页 > 网络编程 > JavaScript > 用javascript 面向对象制作坦克大战(四)

用javascript 面向对象制作坦克大战(四)

来源: 作者: 时间:2016-02-05 11:06 【

我们现在还差一个重要的功能,没错,敌人坦克的创建以及子弹击中敌人坦克时的碰撞检测功能。5 创建敌人坦克完成炮弹碰撞检测5 1 创建敌人坦克对象 敌人坦克和玩家坦克一样,同样
 我们现在还差一个重要的功能,没错,敌人坦克的创建以及子弹击中敌人坦克时的碰撞检测功能。
 
 
5.  创建敌人坦克完成炮弹碰撞检测
 
 
 
5.1   创建敌人坦克对象
 
 
  敌人坦克和玩家坦克一样,同样继承自我们的坦克对象。所以我们在Tank.js中写入以下代码:
 
 
 
 
复制代码
 1 // 敌人坦克对象
 2 EnimyTank = function () {
 3     this.Direction = EnumDirection.Down;
 4     this.BombNum = 1;
 5     this.UI = UtilityClass.CreateE("div", "", "etank", document.getElementById("divMap"));
 6     this.UI.style.backgroundPosition = "0 -" + this.Direction * 40 + "px";
 7 
 8 }
 9 
10 EnimyTank.prototype = new Tank;
复制代码
 
 
  然后在我们的游戏装载对象初始化游戏时创建敌人坦克。
 
 
 
 
1   var enimyT1 = new EnimyTank();
2         enimyT1.XPosition = 0;
3         enimyT1.YPosition = 0;
4         enimyT1.UpdateUI(this._battleField);
5         this._enimyTanks.push(enimyT1);
 
 
5.2   敌人坦克移动和发射炮弹
 
  坦克创建好了,我们怎么让他动起来呢? 很简单,只需要在我们的游戏装载对象中添加一个敌人坦克移动并发射的方法,并且在Run主循环中进行调用就可以了。
 
代码:
 
 
 
 
复制代码
1     for (var i = 0; i < this._enimyTanks.length; i++) {
3             if (this._enimyTanks[i] instanceof Mover) {
4                  this._enimyTanks[i].Move(this._battleField);
5                  if (Math.random() * 100 < 5) { this._enimyTanks[i].Shot(this._battleField) };/* 5%的概率发射炮弹 */
6             }
7         }
复制代码
 
 
  ok,现在我们的坦克可以正常的移动和发射炮弹了。但是我们发现坦克移动的方向不会发生改变,所以还需要一个小小的处理,在我们的Mover对象的Move方法中添加以下代码,敌人坦克就能随机变换方向了。
 
 
 
1     // 敌人坦克有30%几率变换方向
2     if ((this instanceof EnimyTank) && Math.random() * 100 > 30) {
3         this.Direction = parseInt(Math.random() * 4);
4     }
 
 
5.3   炮弹碰撞检测
 
  之前我们炮弹的碰撞检测只写了打到障碍物的检测,所以我们还需要添加炮弹碰撞到坦克的情况。 实现思路很简单,当我们的子弹穿过空地或草地(坦克能停留的两种地形)时,我们检测地图的占有对象是不是坦克就可以了。上代码:
 
 
 
Bomb.js:
 
 
 
 
复制代码
 1             //  如果下一个是草或者空地
 2         else if (nextObj.obj instanceof EmptyB || nextObj.obj instanceof TodB) {
 3             // 玩家炮弹打中敌人坦克
 4             if (nextObj.occupier instanceof EnimyTank && this.Owner instanceof SelfTank) {
 5                 UtilityClass.RemoveE(nextObj.occupier.UI, document.getElementById("divMap"));
 6                 nextObj.occupier.UI = null;
 7                 GameLoader.prototype._enimyTanks.pop();
 8                 nextObj.occupier = null;
 9             }   // 敌人炮弹打中玩家坦克
10             else if (nextObj.occupier instanceof SelfTank && this.Owner instanceof EnimyTank) {
11                 //UtilityClass.RemoveE(nextObj.occupier.UI, document.getElementById("divMap"));
12                 //nextObj.occupier = null;
13             }
14         }
复制代码
 
 
  此时,我们会发现当玩家的炮弹击中敌人后,敌人坦克会随机的占有他的4个方向中的一个单元格。这是什么原因造成的呢?   我们可以想想,当我们的炮弹命中敌人的时候,他有可能正在移动。这时候我们把他移除了,但是他的Move的步进方法还会继续执行,别忘了,我们是用的setInterval,所以他就鬼使神差步进到下一个单元格。 这时候坦克对象移除了,但是占用还在,就会出问题了。
 
  解决的方案很简单,我们在移除坦克时将坦克的UI 已经设置为null了,所以在步进前我们判断他UI的值为null时,我们就停止步进就ok了。代码很简单:
 
 
 
复制代码
1   if (This instanceof EnimyTank) {
2             // 如果敌人坦克被销毁,则停止步进
3             if (This.UI == null) {
4                 clearInterval(subMove);
5             }
6         }
复制代码
 
 
5.4   多个敌人坦克的解决方案
 
  这时候我们还发现一个严重的问题: 我们的敌人坦克是保存在游戏装载对象里的一个数组,当我们消灭敌人坦克时,我们不知道到底该从中移除哪个坦克。
 
  其实这个问题的解决思路相当简单:在初始化敌人坦克时给他一个属性保存他在数组中的索引,当需要消除坦克对象时,我们直接根据索引移除就可以了。
 
1、初始化存储索引
 
  
 
 enimyT1.index = this._enimyTanks.length;
 
 
2、给Array扩展原型方法,移除指定位置的数组。
 
  
 
复制代码
 1 Array.prototype.removeAt = function (index) {
 2     var arr = [], j = 0;
 3     // 遍历数组,过滤指定位置的元素
 4     for (var i = 0; i < this.length; i++) {
 5         if (i != index) {
 6             arr[j++] = this[i];
 7         }
 8     }
 9     return arr;
10 }
复制代码
 
 
3、修改炮弹打中敌人的代码。
 
 
 
复制代码
 1  // 玩家炮弹打中敌人坦克
 2             if (nextObj.occupier instanceof EnimyTank && this.Owner instanceof SelfTank) {
 3                 UtilityClass.RemoveE(nextObj.occupier.UI, document.getElementById("divMap"));
 4                 nextObj.occupier.UI = null;
 5                 var arr = GameLoader.prototype._enimyTanks.removeAt(nextObj.occupier.index);
 6                 // 重置坦克索引
 7                 for (var i = 0; i < arr.length; i++) {
 8                     arr[i].index = i;
 9                 }
10                 GameLoader.prototype._enimyTanks = arr;
11