首页 > 代码库 > 用javascript 面向对象制作坦克大战(三)
用javascript 面向对象制作坦克大战(三)
之前,我们完成了坦克的移动和地图的绘制,这次我们来完成碰撞检测和炮弹的发射。
上代码前来张最新的类图:
3. 碰撞检测
前面我们已经完成了坦克的移动和地图的绘制,下面我们开始写碰撞检测。
3.1 创建碰撞检测对象
我们创建一个对象来做碰撞检测,由于碰撞检测都是在对象移动的时候进行的所以我们让Mover继承我们的碰撞对象。
HitTestObject.js:
1 // 碰撞检测对象 继承自顶级对象 2 HitTestObject = function () { } 3 4 HitTestObject.prototype = new TankObject(); 5 // 碰撞检测 参数为地图对象 返回true则不能移动 6 HitTestObject.prototype.HitTest = function (battleField) { 7 8 var nextObj = this.GetNextBattleFieldCell(battleField); 9 if (nextObj == null) {10 return true;// 场景越界11 }12 // 检测是否是障碍物13 if (nextObj.obj instanceof Barrier) {14 15 if (nextObj.obj instanceof EmptyB) {16 // 判断是否被其他坦克占用 Tank继承自Mover17 return nextObj.occupier instanceof Mover;18 }19 return !nextObj.obj.CanAcross;20 }21 22 23 }24 25 // 返回对象移动下个位置的地图对象26 HitTestObject.prototype.GetNextBattleFieldCell = function (battleField) {27 28 if (this.Direction == EnumDirection.Up && this.YPosition == 0 ||29 this.Direction == EnumDirection.Down && this.YPosition == 12 ||30 this.Direction == EnumDirection.Left && this.XPosition == 0 ||31 this.Direction == EnumDirection.Right && this.XPosition == 1232 ) {33 return null;/* 场景越界 */34 }35 36 var y = this.YPosition;37 var x = this.XPosition;38 var nextAxes = this.GetNextAxes(x, y);39 return battleField[nextAxes.y][nextAxes.x];40 }41 42 // 得到对象的下个位置的坐标43 HitTestObject.prototype.GetNextAxes = function (x, y) {44 var point = { x: x, y: y };45 switch (this.Direction + "") { // 加空字符转换为字符串类型46 case EnumDirection.Up:47 point.y--; break;48 case EnumDirection.Right:49 point.x++; break;50 case EnumDirection.Down:51 point.y++; break;52 case EnumDirection.Left:53 point.x--; break;54 }55 return point;56 }57 58 59 HitTestObject.prototype.OnHitTest = function (battleField) {60 // 预留给炮弹对象重写61 }
这里我们把之前写的地图二维数组对象充分利用上了。通过对象x,y坐标取对应的地图对象,再根据属性判断是否可被穿过,是否已被占用。
3.2 调用碰撞检测
这里需要我们在之前的代码做一系列的更改了。
更改 Mover.js
1、继承碰撞检测对象
Mover.prototype = new HitTestObject();
2、在Mover方法中调用碰撞检测
// 碰撞检测 if (this.HitTest(battleField)) { return this.OnHitTest(battleField); }
3、移动完成后占用新地图对象,清空原对象地图占用。
battleField[nextPoint.y][nextPoint.x].occupier = This; /*占用新位置*/// 清空对象原来位置占有battleField[yp][xp].occupier = null;
还有一些更改就不一一列出了,大家可以下载源码查看。
更改 Frame.js 给方法加上参数。
更改 tank.js UpdateUi方法
初始化坦克时,占有当前位置。
4. 发射炮弹
炮弹可以移动,所以继承自我们的Mover对象。炮弹击中障碍物时会有爆炸效果,所以我们先写爆炸对象。
4.1 爆炸效果对象
Explode.js:
1 // 爆炸效果类 2 Explode = function () { 3 this.container = document.getElementById("divMap"); 4 this.UI = null; 5 this.step = 8; // 共8张图 6 this.speed = 50; // 动画播放速度 7 } 8 9 // 播放爆炸效果10 Explode.prototype.Play = function (x,y) {11 this.UI = UtilityClass.CreateE("div", "", "explode", this.container);12 this.MoveTo(x, y);13 14 var i = 0;15 var This = this;16 var FxTimer = setInterval(function () {17 This.UI.style.backgroundPosition = ‘0 -‘ + i * 60 + ‘px‘;18 i++;19 if (i==This.step) {20 clearInterval(FxTimer);21 This.Stop();22 }23 },this.speed);24 }25 26 // 播放位置 27 Explode.prototype.MoveTo = function (x,y) {28 29 if (this.UI != null) {30 this.UI.style.left = x * 40 - 10 + "px";31 this.UI.style.top = y * 40 - 10 + "px";32 }33 34 }35 36 // 移除dom元素37 Explode.prototype.Stop = function () {38 UtilityClass.RemoveE(this.UI, this.container);39 }
4.2 炮弹对象
Bomb.js:
1 // 炮弹对象,这个对象需要放在TANK对象前面,有先后顺序 2 Bomb = function () { 3 this.Owner = null; 4 this.Power = 1; 5 this.Speed = 7; 6 } 7 8 Bomb.prototype = new Mover(); 9 Bomb.prototype.Load = function (x,y) {10 // 创建炮弹对象,初始化位置11 this.UI = UtilityClass.CreateE("div", "", "bomb", document.getElementById("divMap"))12 this.SetPosition(x * 40, y * 40); /*父类方法*/13 14 }15 16 // 重写HitTest方法17 Bomb.prototype.HitTest = function (battleField) {18 var nextObj = this.GetNextBattleFieldCell(battleField);19 if (nextObj == null) {20 return true;21 }22 // 检测是否是障碍物23 if (nextObj.obj instanceof Barrier) {24 // 河流穿过25 if (this instanceof Bomb && nextObj.obj instanceof RiverB) {26 return false;27 }28 29 return !nextObj.obj.CanAcross;30 }31 32 }33 34 // 重写OnHitTest方法 当炮弹碰撞到不可穿过对象时调用35 Bomb.prototype.OnHitTest = function (battleField) {36 37 // 播放爆炸效果38 var ex = new Explode();39 ex.Play(this.XPosition, this.YPosition);40 this.Owner.BombUsed--; /*已用弹药数减一*/41 // 清空地图占有位置,移除元素42 battleField[this.YPosition][this.XPosition].occupier = null;43 UtilityClass.RemoveE(this.UI, document.getElementById("divMap"));44 45 var nextObj = this.GetNextBattleFieldCell(battleField);46 if (nextObj == null) { return; }47 // 炮弹打到了障碍物48 if (nextObj.obj instanceof Barrier) {49 if (nextObj.obj.CanBeAttacked) {50 nextObj.obj.DefenVal -= this.Power;51 // 障碍物防御值降到0,把障碍物变为空地52 if (nextObj.obj.DefenVal <= 0) {53 var to = new EmptyB();54 to.UI = nextObj.obj.UI;55 to.XPosition = nextObj.obj.XPosition;56 to.YPosition = nextObj.obj.YPosition;57 nextObj.obj = to;58 to.UI.className = "";59 battleField[this.YPosition][this.XPosition].obj.UI.className = "";60 }61 }62 }63 64 }
主要的对象完成了,调用就是水到渠成了,我们需要给坦克添加一个发射炮弹的方法,并在玩家按下空格键时调用就可以了。 大家可以试着自己写下实现。
TankV3.0 下载地址:
http://pan.baidu.com/s/1hqADJYO
用javascript 面向对象制作坦克大战(三)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。