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

  PS:这个坦克大战是在网上下的一段源码之后,自己进行的重写。   写这个的目的是为了巩固自己这段时间对js的学习。整理到博客上,算是对自己近端时间学习js的一个整理。 同时也希望可以帮助到学习js的园友。由于自己也是刚学js不久,所以难免出现错误。如果发现希望给予指正。   这个教程适合熟悉js基本语法和面向对象语法的园友学习。 本身没有太难的东西,这个案例将js面向对象用的比较好,可以作为js面向对象的入门教程。

1.   创建基本对象,实现坦克简单的移动。

1.1    如何在地图中绘制画布?

考虑到浏览器兼容的问题,我们用操作dom的方式来实现游戏对象的绘制和刷新。我们如何存储我们的地图呢? 我们应该把地图用一个二维数组来保存, js中没有二维数组,但是可以通过在一维数组从存储数组来实现。

1.2    代码实现

我们将画布设计为 13 * 13 的一个二维数组,每个元素在地图中对应的长和宽均为40px,可以把整个地图看成由 40px*40p x大小的单元格组成的一个表格,那么我们整个画布的大小为 520px  *  520px ;

1.2.1    创建顶级对象

html代码:

1 <body>
2 <!--地图容器-->
3 <div id="divMap">
4 </div>
5 <div id="debugInfo">
6 </div>
7 </body>
8  

TankObject.js文件:

// 顶级对象
TankObject = function () {
this.XPosition = 0; // 对象在地图(13*13)中的X的位置
this.YPosition = 0;
this.UI = null; // 地图中一个格子的UI
}
// 更改UI静态方法
TankObject.prototype.UpdateUI = function (battlFiled) { }
// 设置位置,参数是这样:1*40,6*40
TankObject.prototype.SetPosition = function (leftPosition, topPosition) {
// 在地图的位置 Math.round四舍五入
this.XPosition = Math.round(leftPosition / 40);
this.YPosition = Math.round(topPosition / 40);
// 设置在窗体上的位置
if (this.UI != null && this.UI.style != null) {
this.UI.style.left = leftPosition + "px";
this.UI.style.top = topPosition + "px";
}
}

这里?我们用X,Y坐标表示对象在地图上的位置。后面我们会将地图中的每个对象都放入二维数组中,这时可以通过X,Y坐标来取得对应的对象。

然后用css中的left和top来控制我们对象在窗体中的位置。(可以移动的对象:坦克,子弹)

1.2.2   创建公用对象

我们还需要创建一个公共的对象,来写入我们常用的一些方法。

Common.js:

 1 // 坦克移动的四个方向
 2 var EnumDirection = {
 3 Up: "0",
 4 Right: "1",
 5 Down: "2",
 6 Left: "3"
 7 };
 8
 9
10 // 通用方法对象
11 var UtilityClass = {
12 // 创建dom元素到parentNode中,可指定id,className
13 CreateE: function (type, id, className, parentNode) {
14 var J = document.createElement(type);
15 if (id) { J.id = id };
16 if (className) { J.className = className };
17 return parentNode.appendChild(J);
18 }, // 移除元素
19 RemoveE: function (obj, parentNode) {
20 parentNode.removeChild(obj);
21 },
22 GetFunctionName: function (context, argumentCallee) {
23 for (var i in context) {
24 if (context[i] == argumentCallee) { return i };
25 }
26 return "";
27 }, // 绑定事件
28 BindFunction: function (obj,func) {
29 return function () {
30 func.apply(obj, arguments);
31 };
32 }
33 };
34
35  

1.2.3    创建移动对象

Mover.js

 1 // 移动对象,继承自顶层对象
 2 Mover = function () {
 3 this.Direction = EnumDirection.Up;
 4 this.Speed = 1;
 5 }
 6 Mover.prototype = new TankObject();
 7 Mover.prototype.Move = function () {
 8 if (this.lock) {
 9 return;/* 停用或者尚在步进中,操作无效 */
10 }
11 // 根据方向设置坦克的背景图片
12 this.UI.style.backgroundPosition = "0 -" + this.Direction * 40 + "px";
13 // 如果方向是上和下,vp就是top;如果方向是上和左,val就是-1
14 var vp = ["top", "left"][((this.Direction == EnumDirection.Up) || (this.Direction == EnumDirection.Down)) ? 0 : 1];
15 var val = ((this.Direction == EnumDirection.Up) || (this.Direction == EnumDirection.Left)) ? -1 : 1;
16 this.lock = true;/* 加锁 */
17 // 把当前对象保存到This
18 var This = this;
19 // 记录对象移动起始位置
20 var startmoveP = parseInt(This.UI.style[vp]);
21 var xp = This.XPosition, yp = This.YPosition;
22 var subMove = setInterval(function () {
23 // 开始移动,每次移动5px
24 This.UI.style[vp] = parseInt(This.UI.style[vp]) + 5 * val + "px";
25 // 每次移动一个单元格 40px
26 if (Math.abs((parseInt(This.UI.style[vp]) - startmoveP)) >= 40) {
27 clearInterval(subMove);
28 This.lock = false;/* 解锁,允许再次步进 */
29 // 记录对象移动后在表格中的位置
30 This.XPosition = Math.round(This.UI.offsetLeft / 40);
31 This.YPosition = Math.round(This.UI.offsetTop / 40);
32
33 }
34 }, 80 - this.Speed * 10);
35
36 }

这里的移动对象继承自我们的顶级对象 ,这里this就代表调用Move方法的对象。

Move对象的功能根据对象的方向和速度进行移动,每次移动5px总共移动40px一个单元格。后面这个对象还会进行扩展,会加入碰撞检测等功能。

1.2.4    创建坦克对象

Tank.js 文件:

 1
 2 //tank对象 继承自Mover
 3 Tank=function(){}
 4
 5 Tank.prototype = new Mover();
 6
 7
 8 // 创建玩家坦克,继承自tank对象
 9 SelfTank = function () {
10 this.UI = UtilityClass.CreateE("div", "", "itank", document.getElementById("divMap"));
11 this.MovingState = false;
12 this.Speed = 4;
13 }
14 SelfTank.prototype = new Tank();
15 // 设置坦克的位置
16 SelfTank.prototype.UpdateUI = function () {
17 this.UI.className = "itank";
18 // 顶级对象方法,设置坦克的位置
19 this.SetPosition(this.XPosition * 40, this.YPosition * 40);
20 }

现在只创建了玩家坦克,后面我们还会往里添加敌人坦克。

1.2.5    创建游戏装载对象(核心)

 1 // 游戏载入对象 整个游戏的核心对象
 2 GameLoader = function () {
 3 this.mapContainer = document.getElementById("divMap"); // 存放游戏地图的div
 4 this._selfTank = null; // 玩家坦克
 5 this._gameListener = null; // 游戏主循环计时器id
 6 }
 7 GameLoader.prototype = {
 8 Begin: function () {
 9 // 初始化玩家坦克
10 var selfT = new SelfTank();
11 selfT.XPosition = 4;
12 selfT.YPosition = 12;
13 selfT.UpdateUI();
14 this._selfTank = selfT;
15
16 // 添加按键事件
17 var warpper = UtilityClass.BindFunction(this, this.OnKeyDown);
18 window.onkeydown = document.body.onkeydown = warpper;
19 warpper = UtilityClass.BindFunction(this, this.OnKeyUp);
20 window.onkeyup = document.body.onkeyup = warpper;
21 // 游戏主循环
22 warpper = UtilityClass.BindFunction(this, this.Run);
23 /*长定时器监听控制键*/
24 this._gameListener = setInterval(warpper, 20);
25
26 }
27 // 键盘按下玩家坦克开始移动
28 , OnKeyDown: function (e) {
29 switch ((window.event || e).keyCode) {
30 case 37:
31 this._selfTank.Direction = EnumDirection.Left;
32 this._selfTank.MovingState = true;
33 break;     //左
34 case 38:
35 this._selfTank.Direction = EnumDirection.Up;
36 this._selfTank.MovingState = true;
37 break;     //上
38 case 39:
39 this._selfTank.Direction = EnumDirection.Right;
40 this._selfTank.MovingState = true;
41 break;     //右
42 case 40:
43 this._selfTank.Direction = EnumDirection.Down;
44 this._selfTank.MovingState = true;
45 break;     //下
46 }
47
48 }
49 // 按键弹起停止移动
50 , OnKeyUp: function (e) {
51 switch ((window.event || e).keyCode) {
52 case 37:
53 case 38:
54 case 39:
55 case 40:
56 this._selfTank.MovingState = false;
57 break;
58 }
59 }
60 /*游戏主循环运行函数,游戏的心脏,枢纽*/
61 , Run: function () {
62 if (this._selfTank.MovingState) {
63 this._selfTank.Move();
64 }
65 }
66
67
68 };
69  

游戏装载对象代码看起来很多,其实就做了两件事情:

1、创建玩家坦克对象。

2、添加按键监听事件,当玩家按下移动键调用坦克Move方法移动坦克。

时间: 2024-10-22 18:16:56

javascript 面向对象制作坦克大战 (一)的相关文章

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

我们现在还差一个重要的功能,没错,敌人坦克的创建以及子弹击中敌人坦克时的碰撞检测功能. 5.  创建敌人坦克完成炮弹碰撞检测 5.1   创建敌人坦克对象 敌人坦克和玩家坦克一样,同样继承自我们的坦克对象.所以我们在Tank.js中写入以下代码: 1 // 敌人坦克对象 2 EnimyTank = function () { 3 this.Direction = EnumDirection.Down; 4 this.BombNum = 1; 5 this.UI = UtilityClass.Cr

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

之前,我们完成了坦克的移动和地图的绘制,这次我们来完成碰撞检测和炮弹的发射. 上代码前来张最新的类图: 3. 碰撞检测 前面我们已经完成了坦克的移动和地图的绘制,下面我们开始写碰撞检测. 3.1    创建碰撞检测对象 我们创建一个对象来做碰撞检测,由于碰撞检测都是在对象移动的时候进行的所以我们让Mover继承我们的碰撞对象. HitTestObject.js:   这里我们把之前写的地图二维数组对象充分利用上了.通过对象x,y坐标取对应的地图对象,再根据属性判断是否可被穿过,是否已被占用. 3

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

2.   完善地图 我们的地图中有空地,墙,钢,草丛,水,总部等障碍物. 我们可以把这些全部设计为对象. 2.1  创建障碍物对象群 对象群保存各种地图上的对象,我们通过对象的属性来判断对象是否可以被穿过或被攻击. Barrier.js:   2.2    写入地图的数据. 在Common.js 中添加以下代码:   2.3    绘制地图 准备工作做完了,下面开始上大菜,绘制地图.前面有提到我们的地图为 13 * 13 的表格.所以我们在游戏装载对象添加行和列两个属性,并且添加初始化地图方法.

html5制作坦克大战

全部html5都采用绘图技术完成.坦克是画出来的.(坦克,子弹,墙,水,草坪) 首先我们画出坦克. 坦克是两边两个矩形,中间一个大矩形,矩形了有一个圆,还有一根线. 画出坦克的思路是以坦克的左上角为参照点,画出坦克的其他部分. 这样的好处是,当左上角的点发生改变是,坦克才能发生改变. 不使用图片的原因就是图片是比较耗费资源的.因为图片的像素点很大. tankGame1.html的代码 <!DOCTYPE html><html><head><meta charset

【blade04】用面向对象的方法写javascript坦克大战

前言 javascript与程序的语言比如C#或者java不一样,他并没有“类”的概念,虽然最新的ECMAScript提出了Class的概念,我们却没有怎么用 就单以C#与Java来说,要到真正理解面向对象的程度也是要花一点功夫的,特别是初学的同学往往意识不到面向对象的好处,因为我们编码的流程是这样的 ① 面向过程 这个时候,我们要思想一个东西,往往就用一个大代码段完成了 ② 方法重用 我们有时候再也受不了重复的代码在一个地方存在了,于是这个时候我们会将相同的逻辑抽象为一个方法 ③ 当代码达到一

汉顺平html5课程分享:6小时制作经典的坦克大战!

记起自己去年參加的一次面试,在做过Java多年的面试官面前发挥的并不好,但他一听说我会html5,立刻眼睛发亮.无论不顾的想要和我签约.. .所以.如今为工作犯愁的朋友们,学好html5,绝对会为你找到好工作加入重要砝码. html5 大致是 (html+css3+javascript apis).一句话: html5 支持了css3 的强大的选择器和动画等功能+ 支持javascript 非常多新的函数.所以html5就非常强大了. 所以在此特意韩顺平老师的html5课程-6小时编写经典坦克大

java制作简单的坦克大战

坦克大战是我们小时候玩红白机时代的经典游戏,看到有不少小伙伴都使用各种语言实现了一下,手痒痒,也使用java做的一个比较简单的坦克大战,主要面向于学过Java的人群,与学了一段时间的人,有利于面向对象思想的提高,推荐给大家. 详情请参照注释,这里就不多废话了,实现一下儿时的经典而已. Blood.java ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 3

坦克大战(一)

坦克大战(一) 相信大家对坦克大战都不陌生,并且网上也有很多用java实现的小程序,最近用了几天时间将其使用javaScript语言通过面向对象的方式实现,在实现的过程中吸收了很多新的知识,现在趁着程序即将完成之际将其记录下来. 废话不多说,先上程序源码:https://github.com/safemen/TankGame2.0.git 项目需求 在写程序之前,我们需要先大体的了解一下项目的一些需求和注意事项,方便以后的开发. 程序在运行之前会有从下到上的开场动画,然后鼠标点击选择游戏的人数,

C++代码之坦克大战(1)

对坦克大战情有独钟是因为大学时候第一次参加程序设计比赛就做的这个游戏.当时用的语言是Java,那个比赛让我悟出了面向对象的强大之处,我也是从那时开始接触设计模式的.对我而言,坦克大战有着非同寻常的意义,所以一定要带大家用C++实现一下. 坦克大战 我们依然使用EasyX在控制台程序中制作这个游戏程序.这一篇的主要任务是在屏幕上画出一个白色的主战坦克,可以通过方向键控制它的前进方向.效果如下: 下面我们正式开始. 画布类 在这个工程中,我们将EasyX画布相关的功能封装在一个Graphic类中,创