用javascript 面向对象制作坦克大战(四)
我们现在还差一个重要的功能,没错,敌人坦克的创建以及子弹击中敌人坦克时的碰撞检测功能。
5. 创建敌人坦克完成炮弹碰撞检测
5.1 创建敌人坦克对象
敌人坦克和玩家坦克一样,同样继承自我们的坦克对象。所以我们在Tank.js中写入以下代码:
// 敌人坦克对象
EnimyTank = function () {
this.Direction = EnumDirection.Down;
this.BombNum = 1;
this.UI = UtilityClass.CreateE("div", "", "etank", document.getElementById("divMap"));
this.UI.style.backgroundPosition = "0 -" + this.Direction * 40 + "px"; } EnimyTank.prototype = new Tank;
然后在我们的游戏装载对象初始化游戏时创建敌人坦克。
var enimyT1 = new EnimyTank();
enimyT1.XPosition = 0;
enimyT1.YPosition = 0;
enimyT1.UpdateUI(this._battleField);
this._enimyTanks.push(enimyT1);
5.2 敌人坦克移动和发射炮弹
坦克创建好了,我们怎么让他动起来呢? 很简单,只需要在我们的游戏装载对象中添加一个敌人坦克移动并发射的方法,并且在Run主循环中进行调用就可以了。
代码:
for (var i = 0; i < this._enimyTanks.length; i++) {
if (this._enimyTanks[i] instanceof Mover) {
this._enimyTanks[i].Move(this._battleField);
if (Math.random() * 100 < 5) { this._enimyTanks[i].Shot(this._battleField) };/* 5%的概率发射炮弹 */
}
}
ok,现在我们的坦克可以正常的移动和发射炮弹了。但是我们发现坦克移动的方向不会发生改变,所以还需要一个小小的处理,在我们的Mover对象的Move方法中添加以下代码,敌人坦克就能随机变换方向了。
// 敌人坦克有30%几率变换方向
if ((this instanceof EnimyTank) && Math.random() * 100 > 30) {
this.Direction = parseInt(Math.random() * 4);
}
5.3 炮弹碰撞检测
之前我们炮弹的碰撞检测只写了打到障碍物的检测,所以我们还需要添加炮弹碰撞到坦克的情况。 实现思路很简单,当我们的子弹穿过空地或草地(坦克能停留的两种地形)时,我们检测地图的占有对象是不是坦克就可以了。上代码:
Bomb.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;
}
}
此时,我们会发现当玩家的炮弹击中敌人后,敌人坦克会随机的占有他的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 面向对象制作坦克大战 (一)
PS:这个坦克大战是在网上下的一段源码之后,自己进行的重写. 写这个的目的是为了巩固自己这段时间对js的学习.整理到博客上,算是对自己近端时间学习js的一个整理. 同时也希望可以帮助到学习js的园 ...
- 用javascript 面向对象制作坦克大战(三)
之前,我们完成了坦克的移动和地图的绘制,这次我们来完成碰撞检测和炮弹的发射. 上代码前来张最新的类图: 3. 碰撞检测 前面我们已经完成了坦克的移动和地图的绘制,下面我们开始写碰撞检测. 3. ...
- 用javascript 面向对象制作坦克大战(二)
2. 完善地图 我们的地图中有空地,墙,钢,草丛,水,总部等障碍物. 我们可以把这些全部设计为对象. 2.1 创建障碍物对象群 对象群保存各种地图上的对象,我们通过对象的属性来判断对 ...
- html5制作坦克大战
全部html5都采用绘图技术完成.坦克是画出来的.(坦克,子弹,墙,水,草坪) 首先我们画出坦克. 坦克是两边两个矩形,中间一个大矩形,矩形了有一个圆,还有一根线. 画出坦克的思路是以坦克的左上角为参 ...
- Java坦克大战 (四) 之子弹的产生
本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...
- javascript面向对象精要第四章构造函数和原型对象整理精要
- 【blade04】用面向对象的方法写javascript坦克大战
前言 javascript与程序的语言比如C#或者java不一样,他并没有“类”的概念,虽然最新的ECMAScript提出了Class的概念,我们却没有怎么用 就单以C#与Java来说,要到真正理解面 ...
- 汉顺平html5课程分享:6小时制作经典的坦克大战!
记起自己去年參加的一次面试,在做过Java多年的面试官面前发挥的并不好,但他一听说我会html5,立刻眼睛发亮.无论不顾的想要和我签约.. .所以.如今为工作犯愁的朋友们,学好html5,绝对会为你找 ...
- javascript面向对象系列第四篇——选项卡的实现
前面的话 面向对象的应用并非只是读几本书那么容易,需要有大量的工程实践做基础才能真正理解并学会使用它.本文将用面向对象的技术来制作一个简单的选项卡 图示说明 由图示结果看到,这是一个非常简单的选项卡. ...
随机推荐
- Ubuntu 14.04 + Linux 3.14.34 系统调用实现文件拷贝
采用 64位系统, ubuntu 14.04 + 新内核linux-3.14.34 下载地址https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.1 ...
- hdu2717 Catch That Cow
http://acm.hdu.edu.cn/showproblem.php?pid=2717 //水搜... #include<stdio.h> #include<math.h> ...
- 欧拉工程第58题:Spiral primes
题目链接 Java程序 package projecteuler51to60; import java.math.BigInteger; import java.util.Iterator; impo ...
- 理解maven
1.理解“仓库” 首次运行完mvn -version后,会在用户目录下创建一个.m2的目录(比如:C:\Users\当前用户名\.m2\),这个目录是maven的“本地仓库”,仓库是maven中一个很 ...
- http报文在网络中是明文传输的,所以不安全。HTtp必然来临
HTTP数据在网络中裸奔 HTTP明文协议的缺陷,是导致数据泄露.数据篡改.流量劫持.钓鱼攻击等安全问题的重要原因.HTTP协议无法加密数据,所有通信数据都在网络中明文“裸奔”.通过网络的嗅探设备及一 ...
- Web 技术人员需知的Web 缓存知识
最近的译文距今已有4年之久,原文有一定的更新.今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~ ...
- 1、探究java方法参数传递——引用传递?值传递!
原创博文,转载请注明出处.谢谢~~ java程序运行时,其对象是怎么进行放置和安排的呢?内存是怎么分配的呢?理解好这个很有好处!java有5个地方可以存储数据: 1.寄存器.这是最快的存储区,位于处理 ...
- Windows下IIS以FastCGI模式运行PHP
由于PHP5.3 的改进,原有的IIS 通过isapi 方式解析PHP脚本已经不被支持,PHP从5.3.0 以后的版本开始使用微软的 fastcgi 模式,这是一个更先进的方式,运行速度更快,更稳定. ...
- Regex Tester 安装教程
下载com.brosinski.eclipse.regex_1.4.0.jar 地址:https://github.com/sbrosinski/RegexTester 下载之后把jar包粘贴到${e ...
- nyoj-257 郁闷的C小加(一) 前缀表达式变后缀
郁闷的C小加(一) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说 ...