用javascript 面向对象制作坦克大战(四)
2014-11-28 22:07
190 查看
我们现在还差一个重要的功能,没错,敌人坦克的创建以及子弹击中敌人坦克时的碰撞检测功能。
View Code
此时,我们会发现当玩家的炮弹击中敌人后,敌人坦克会随机的占有他的4个方向中的一个单元格。这是什么原因造成的呢? 我们可以想想,当我们的炮弹命中敌人的时候,他有可能正在移动。这时候我们把他移除了,但是他的Move的步进方法还会继续执行,别忘了,我们是用的setInterval,所以他就鬼使神差步进到下一个单元格。 这时候坦克对象移除了,但是占用还在,就会出问题了。
解决的方案很简单,我们在移除坦克时将坦克的UI 已经设置为null了,所以在步进前我们判断他UI的值为null时,我们就停止步进就ok了。代码很简单:
其实这个问题的解决思路相当简单:在初始化敌人坦克时给他一个属性保存他在数组中的索引,当需要消除坦克对象时,我们直接根据索引移除就可以了。
1、初始化存储索引
2、给Array扩展原型方法,移除指定位置的数组。
3、修改炮弹打中敌人的代码。
这里有一个重置索引的代码,大家可能不明白为什么这么做。 当我们移除掉一个坦克后,数组的元素个数变了,所以原来的数组索引有可能失效。所以我们只要重置一下,就ok了。
大致的功能已经出来了,肯定有一些bug和待完善的地方。列如坦克的移动和炮弹的发射不兼容,玩家子弹和敌人子弹碰撞时应该消除... 还有一些功能未实现:玩家坦克被击中消失、游戏道具、敌人坦克生成、计分、关卡、玩家自己绘制地图。 没有错,我打算把这些难题交给大家了。 写这个博客主要的目的已经达到了:学习js面向对象。希望大家有时间继续完善这个游戏,在完成的过程中可以学到很多东西。 感谢各位听我啰嗦。
最后这个版本的下载地址:
http://pan.baidu.com/s/1pJ3DWKV
5. 创建敌人坦克完成炮弹碰撞检测
5.1 创建敌人坦克对象
敌人坦克和玩家坦克一样,同样继承自我们的坦克对象。所以我们在Tank.js中写入以下代码:// 如果下一个是草或者空地 else if (nextObj.obj instanceof EmptyB || nextObj.obj instanceof TodB) { // 玩家炮弹打中敌人坦克 if (nextObj.occupier instanceof EnimyTank && this.Owner instanceof SelfTank) { UtilityClass.RemoveE(nextObj.occupier.UI, document.getElementById("divMap")); nextObj.occupier.UI = null; GameLoader.prototype._enimyTanks.pop(); nextObj.occupier = null; } // 敌人炮弹打中玩家坦克 else if (nextObj.occupier instanceof SelfTank && this.Owner instanceof EnimyTank) { //UtilityClass.RemoveE(nextObj.occupier.UI, document.getElementById("divMap")); //nextObj.occupier = null; } }
View Code
此时,我们会发现当玩家的炮弹击中敌人后,敌人坦克会随机的占有他的4个方向中的一个单元格。这是什么原因造成的呢? 我们可以想想,当我们的炮弹命中敌人的时候,他有可能正在移动。这时候我们把他移除了,但是他的Move的步进方法还会继续执行,别忘了,我们是用的setInterval,所以他就鬼使神差步进到下一个单元格。 这时候坦克对象移除了,但是占用还在,就会出问题了。
解决的方案很简单,我们在移除坦克时将坦克的UI 已经设置为null了,所以在步进前我们判断他UI的值为null时,我们就停止步进就ok了。代码很简单:
if (This instanceof EnimyTank) { // 如果敌人坦克被销毁,则停止步进 if (This.UI == null) { clearInterval(subMove); } }
5.4 多个敌人坦克的解决方案
这时候我们还发现一个严重的问题: 我们的敌人坦克是保存在游戏装载对象里的一个数组,当我们消灭敌人坦克时,我们不知道到底该从中移除哪个坦克。其实这个问题的解决思路相当简单:在初始化敌人坦克时给他一个属性保存他在数组中的索引,当需要消除坦克对象时,我们直接根据索引移除就可以了。
1、初始化存储索引
enimyT1.index = this._enimyTanks.length;
2、给Array扩展原型方法,移除指定位置的数组。
Array.prototype.removeAt = function (index) { var arr = [], j = 0; // 遍历数组,过滤指定位置的元素 for (var i = 0; i < this.length; i++) { if (i != index) { arr[j++] = this[i]; } } return arr; }
3、修改炮弹打中敌人的代码。
// 玩家炮弹打中敌人坦克 if (nextObj.occupier instanceof EnimyTank && this.Owner instanceof SelfTank) { UtilityClass.RemoveE(nextObj.occupier.UI, document.getElementById("divMap")); nextObj.occupier.UI = null; var arr = GameLoader.prototype._enimyTanks.removeAt(nextObj.occupier.index); // 重置坦克索引 for (var i = 0; i < arr.length; i++) { arr[i].index = i; } GameLoader.prototype._enimyTanks = arr; nextObj.occupier = null; }
这里有一个重置索引的代码,大家可能不明白为什么这么做。 当我们移除掉一个坦克后,数组的元素个数变了,所以原来的数组索引有可能失效。所以我们只要重置一下,就ok了。
大致的功能已经出来了,肯定有一些bug和待完善的地方。列如坦克的移动和炮弹的发射不兼容,玩家子弹和敌人子弹碰撞时应该消除... 还有一些功能未实现:玩家坦克被击中消失、游戏道具、敌人坦克生成、计分、关卡、玩家自己绘制地图。 没有错,我打算把这些难题交给大家了。 写这个博客主要的目的已经达到了:学习js面向对象。希望大家有时间继续完善这个游戏,在完成的过程中可以学到很多东西。 感谢各位听我啰嗦。
最后这个版本的下载地址:
http://pan.baidu.com/s/1pJ3DWKV
相关文章推荐
- 用javascript 面向对象制作坦克大战(二)
- 用javascript 面向对象制作坦克大战(三)
- javascript 面向对象制作坦克大战 (一)
- 基于ECMA 的JavaScript 的面向对象程序设计
- JavaScript 面向对象程序设计(上)——封装
- JavaScript 面向对象程序设计(上)——封装(转)
- JavaScript 面向对象程序设计(下)——继承与多态(转)
- JavaScript的面向对象机理2)-继承
- JavaScript 与面向对象实战.
- AJAX语言——对象面向的JavaScript
- JavaScript 面向对象程序设计(下)——继承与多态
- [原创] 面向对象之JavaScript脚本也疯狂!--OxScript反射功能预览
- 谈谈javascript的面向对象
- JavaScript面向对象特性实践一
- JavaScript的面向对象程序设计
- JavaScript 面向对象程序设计(上)——封装[转]
- JavaScript的面向对象机理1)-类
- 面向对象的 Javascript 面向对象基础
- (转)JavaScript 面向对象程序设计(上)——封装
- Javascript的面向对象