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

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

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

1.1    如何在地图中绘制画布

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

1.2    代码实现

我们将画布设计为 13 * 13 的一个二维数组,每个元素在地图中对应的长和宽均为40px,可以把整个地图看成由 40px*40p x大小的单元格组成的一个表格,那么我们整个画布的大小为 520px  *  520px ;
 
   上代码前先给大家来一张对象关系图:

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方法移动坦克。

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

(0)

相关推荐

  • javascript 模拟坦克大战游戏(html5版)附源码下载

    一.总结关键点和遇到的问题 1.javascript中的继承,最好父类只提供方法共享,属性写到各自子类中,避免父类和子类的构造函数混杂. 2.prototype模拟继承的代码,应写在所有方法定义之前,否则原型对象被改变,方法就变成了未定义,如: 复制代码 代码如下: Hero.prototype = new Tank (0, 0, 0); Hero.prototype.constructor = Hero; Hero.prototype.addLife = function(){ this.li

  • JavaScript制作简易的微信打飞机

    简单的用JavaScript模拟微信打飞机,部分功能还不完善,刚开始写,还有很多不足,还望大家多多指出. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title></title> <meta http-equiv

  • 使用 TypeScript 重新编写的 JavaScript 坦克大战游戏代码

    源码下载 源码我已经上传到 CSDN 了,无需资源分,下载地址:http://download.csdn.net/detail/zgynhqf/8565873. 源码使用 VS 2013 +TypeScript 1.4 进行开发.打开后,显示如下图: JsTankGame 1.0:老的使用 JS 编写的坦克游戏. JsTankGame 2.0:新的使用 TS 直接翻译过来的游戏. JsTankGame:在 2.0 的基础上,对类型进行了重构后的新游戏. 重构步骤 由于老的 JS 游戏是采用 MS

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

    2.   完善地图 我们的地图中有空地,墙,钢,草丛,水,总部等障碍物. 我们可以把这些全部设计为对象. 2.1  创建障碍物对象群 对象群保存各种地图上的对象,我们通过对象的属性来判断对象是否可以被穿过或被攻击.   Barrier.js: 复制代码 代码如下: // 障碍物基类对象,继承自TankObject  Barrier = function () {      this.DefenVal = 1;  // 防御力      this.CanBeAttacked = true;  //

  • JS写的贪吃蛇游戏(个人练习)

    JS贪吃蛇游戏,个人练习之用,放在这备份一下,   复制代码 代码如下: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>JS贪吃蛇-练习</t

  • 纯JS实现五子棋游戏兼容各浏览器(附源码)

    纯JS五子棋(各浏览器兼容) 效果图:  代码下载 HTML代码 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;"> <title>五子棋</title> <link rel="stylesheet" type="text/

  • JavaScript原生编写《飞机大战坦克》游戏完整实例

    先来看看开始的界面图 实现思路: 1.打开页面,背景开始走动: 2.点击开始,飞机开始不断发射子弹,敌人随机出现在上方: 3.当敌人碰到子弹,敌人消失: 4.当敌人和飞机相遇,飞机死亡,结束游戏: html页面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>飞机大战</title> <link r

  • 纯javascript模仿微信打飞机小游戏

    七夕情人节也不要忘了打游戏喔喔-,下面小编为大家准备的情人节礼物之纯javascript模仿微信打飞机小游戏分享给天下的情人们. 首先给大家展示效果图: 查看演示      源码下载 纯JavaScript模仿微信打飞机游戏,做网页小游戏的借鉴下,界面设计是竖长形仿手机屏幕风格,游戏效果流畅.具有分数统计,里面的JS封装类中包括有创建飞机类.飞机移动行为控制,创建子弹类,产生min到max之间的随机数,判断本方飞机是否移出边界,如果移出边界,则取消mousemove事件,反之加上mousemov

  • JavaScript 小型打飞机游戏实现原理说明

    玩法说明:上下左右控制移动,空格发弹. 每打中一个敌机就加100分,每提升5000分,玩家的飞机的一次发弹数就加一,最多四,被敌机撞到或者让敌机飞到底部就算输.... 演示代码:http://demo.jb51.net/js/FlyBeat/index.html 游戏目前的功能还是比较简单的....貌似就贴个源码不太好,所以这次还是写写思路... 游戏主要分为4个js文件,4个js文件分别包含4个类. 1:飞机类---Flyer 复制代码 代码如下: //飞机对应的dom元素 this.dom

  • javascript 制作坦克大战游戏初步 图片与代码

    学了一阵子的javascript,该做点东西,虽然东西还是东拼西凑,见笑.方向键控制坦克移动,回车键发射炸弹.其他的功能敌方坦克那些还没写. javascript坦克游戏初步|阿会楠练习作品 body{ background:black; } #tanke{ position:absolute; left:500px; top:200px; } var i = 0; var bombLeftArray = new Array(100);//存放炸弹信息x var bombTopArray = n

随机推荐