手机
当前位置:查字典教程网 >编程开发 >Javascript教程 >javascript制作坦克大战全纪录(1)
javascript制作坦克大战全纪录(1)
摘要:PS:这个坦克大战是在网上下的一段源码之后,自己进行的重写。本身没有太难的东西,这个案例将js面向对象用的比较好,可以作为js面向对象的入门...

PS:这个坦克大战是在网上下的一段源码之后,自己进行的重写。本身没有太难的东西,这个案例将js面向对象用的比较好,可以作为js面向对象的入门教程。

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

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

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

1.2 代码实现

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

上代码前先给大家来一张对象关系图:

javascript制作坦克大战全纪录(1)1

1.2.1 创建顶级对象

html代码:

复制代码 代码如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

<head>

<title>坦克大战</title>

<link rel=stylesheet href="css/main.css" />

<script src="js/Common.js"></script>

<script src="js/TankObject.js"></script>

<script src="js/Mover.js"></script>

<script src="js/Tank.js"></script>

<script src="js/Frame.js"></script>

<script>

window.onload = function () {

// 调用游戏装载对象

var loader = new GameLoader();

loader.Begin();

}

</script>

</head>

<body>

<>

<div id="divMap">

</div>

<div id="debugInfo">

</div>

</body>

</html>

TankObject.js文件:

复制代码 代码如下:

// 顶级对象

TankObject = function () {

this.XPosition = 0; // 对象在地图(13*13)中的X的位置

this.YPosition = 0;

this.UI = null; // dom元素

}

// 更改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:

复制代码 代码如下:

// 坦克移动的四个方向

var EnumDirection = {

Up: "0",

Right: "1",

Down: "2",

Left: "3"

};

// 通用方法对象

var UtilityClass = {

// 创建dom元素到parentNode中,可指定id,className

CreateE: function (type, id, className, parentNode) {

var J = document.createElement(type);

if (id) { J.id = id };

if (className) { J.className = className };

return parentNode.appendChild(J);

}, // 移除元素

RemoveE: function (obj, parentNode) {

parentNode.removeChild(obj);

},

GetFunctionName: function (context, argumentCallee) {

for (var i in context) {

if (context[i] == argumentCallee) { return i };

}

return "";

}, // 绑定事件,返回func方法,this为传入的obj

BindFunction: function (obj,func) {

return function () {

func.apply(obj, arguments);

};

}

};

1.2.3 创建移动对象

Mover.js

复制代码 代码如下:

// 移动对象,继承自顶层对象

Mover = function () {

this.Direction = EnumDirection.Up;

this.Speed = 1;

}

Mover.prototype = new TankObject();

Mover.prototype.Move = function () {

if (this.lock) {

return;/* 停用或者尚在步进中,操作无效 */

}

// 根据方向设置坦克的背景图片

this.UI.style.backgroundPosition = "0 -" + this.Direction * 40 + "px";

// 如果方向是上和下,vp就是top;如果方向是上和左,val就是-1

var vp = ["top", "left"][((this.Direction == EnumDirection.Up) || (this.Direction == EnumDirection.Down)) ? 0 : 1];

var val = ((this.Direction == EnumDirection.Up) || (this.Direction == EnumDirection.Left)) ? -1 : 1;

this.lock = true;/* 加锁 */

// 把当前对象保存到This

var This = this;

// 记录对象移动起始位置

var startmoveP = parseInt(This.UI.style[vp]);

var xp = This.XPosition, yp = This.YPosition;

var subMove = setInterval(function () {

// 开始移动,每次移动5px

This.UI.style[vp] = parseInt(This.UI.style[vp]) + 5 * val + "px";

// 每次移动一个单元格 40px

if (Math.abs((parseInt(This.UI.style[vp]) - startmoveP)) >= 40) {

clearInterval(subMove);

This.lock = false;/* 解锁,允许再次步进 */

// 记录对象移动后在表格中的位置

This.XPosition = Math.round(This.UI.offsetLeft / 40);

This.YPosition = Math.round(This.UI.offsetTop / 40);

}

}, 80 - this.Speed * 10);

}

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

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

1.2.4 创建坦克对象

Tank.js 文件:

复制代码 代码如下:

//tank对象 继承自Mover

Tank=function(){}

Tank.prototype = new Mover();

// 创建玩家坦克,继承自tank对象

SelfTank = function () {

this.UI = UtilityClass.CreateE("div", "", "itank", document.getElementById("divMap"));

this.MovingState = false;

this.Speed = 4;

}

SelfTank.prototype = new Tank();

// 设置坦克的位置

SelfTank.prototype.UpdateUI = function () {

this.UI.className = "itank";

// 顶级对象方法,设置坦克的位置

this.SetPosition(this.XPosition * 40, this.YPosition * 40);

}

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

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

复制代码 代码如下:

// 游戏载入对象 整个游戏的核心对象

GameLoader = function () {

this.mapContainer = document.getElementById("divMap"); // 存放游戏地图的div

this._selfTank = null; // 玩家坦克

this._gameListener = null; // 游戏主循环计时器id

}

GameLoader.prototype = {

Begin: function () {

// 初始化玩家坦克

var selfT = new SelfTank();

selfT.XPosition = 4;

selfT.YPosition = 12;

selfT.UpdateUI();

this._selfTank = selfT;

// 添加按键事件

var warpper = UtilityClass.BindFunction(this, this.OnKeyDown);

window.onkeydown = document.body.onkeydown = warpper;

warpper = UtilityClass.BindFunction(this, this.OnKeyUp);

window.onkeyup = document.body.onkeyup = warpper;

// 游戏主循环

warpper = UtilityClass.BindFunction(this, this.Run);

/*长定时器监听控制键*/

this._gameListener = setInterval(warpper, 20);

}

// 键盘按下玩家坦克开始移动

, OnKeyDown: function (e) {

switch ((window.event || e).keyCode) {

case 37:

this._selfTank.Direction = EnumDirection.Left;

this._selfTank.MovingState = true;

break; //左

case 38:

this._selfTank.Direction = EnumDirection.Up;

this._selfTank.MovingState = true;

break; //上

case 39:

this._selfTank.Direction = EnumDirection.Right;

this._selfTank.MovingState = true;

break; //右

case 40:

this._selfTank.Direction = EnumDirection.Down;

this._selfTank.MovingState = true;

break; //下

}

}

// 按键弹起停止移动

, OnKeyUp: function (e) {

switch ((window.event || e).keyCode) {

case 37:

case 38:

case 39:

case 40:

this._selfTank.MovingState = false;

break;

}

}

/*游戏主循环运行函数,游戏的心脏,枢纽*/

, Run: function () {

if (this._selfTank.MovingState) {

this._selfTank.Move();

}

}

};

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

1、创建玩家坦克对象。

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

总结:到这里我们的坦克可以通过按键自由的移动了。下一步我们需要完善地图和碰撞检测。

【javascript制作坦克大战全纪录(1)】相关文章:

javascript生成不重复的随机数

javascript瀑布流式图片懒加载实例解析与优化

javascript实现table表格隔行变色的方法

Javascript调用XML制作连动下拉列表框

JavaScript中的私有成员

Javascript生成全局唯一标识符(GUID,UUID)的方法

javascript动态设置样式style实例分析

javascript实现图片跟随鼠标移动效果的方法

javascript中动态函数用法

javascript实时显示当天日期的方法

精品推荐
分类导航