亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

javascript制作坦克大戰全紀錄(1)

2019-11-20 13:51:42
字體:
來源:轉載
供稿:網友

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

總結:到這里我們的坦克可以通過按鍵自由的移動了。下一步我們需要完善地圖和碰撞檢測。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日本中文字幕久久看| 亚洲视频精品在线| 中文字幕免费精品一区高清| 欧美电影免费观看高清完整| 欧美一级片在线播放| 欧美国产在线电影| 日韩欧美高清在线视频| 狠狠躁夜夜躁人人爽超碰91| 91精品在线看| yw.139尤物在线精品视频| 国产在线视频91| 久久精品国产96久久久香蕉| 91在线国产电影| 亚洲色图在线观看| 亚洲va欧美va国产综合剧情| 最近中文字幕日韩精品| 欧美视频13p| 欧美最猛性xxxx| 亚洲精品永久免费精品| 欧美成人精品激情在线观看| 国产精品亚洲综合天堂夜夜| 久久九九免费视频| 在线精品国产欧美| 黄网站色欧美视频| 亚洲欧美日韩中文在线| 亚洲国产精品电影在线观看| 55夜色66夜色国产精品视频| 欧美性xxxx极品高清hd直播| 欧洲永久精品大片ww免费漫画| 欧美日韩国产一区二区三区| 国产综合久久久久| 国产69久久精品成人看| 成人欧美在线观看| 欧美精品在线第一页| 国产精品91在线观看| 欧美一性一乱一交一视频| 亚洲日本欧美中文幕| 亚洲欧美日韩一区二区三区在线| 国产日韩欧美夫妻视频在线观看| 大量国产精品视频| 亚洲va久久久噜噜噜久久天堂| 国产一区二区激情| 久久av在线看| 国产噜噜噜噜久久久久久久久| 国产精品久久久久久久美男| 亚洲美女精品成人在线视频| 国产成人亚洲精品| 欧美激情a∨在线视频播放| 亚洲a级在线播放观看| 亚洲欧美第一页| 欧美中文字幕在线观看| 国产精品av免费在线观看| 精品视频久久久久久| 91久久久在线| 欧美激情免费在线| 精品日本高清在线播放| 国产成人精品av| 国产精品久久久久久av福利软件| 国产亚洲欧洲高清一区| 亚洲国产精品大全| 97超级碰在线看视频免费在线看| 久久综合伊人77777| 国产精品高精视频免费| 欧美天堂在线观看| 精品人伦一区二区三区蜜桃网站| 在线视频国产日韩| 国产主播喷水一区二区| 国产精品久久久久9999| 成人性生交大片免费看视频直播| 在线电影av不卡网址| 日本精品视频在线播放| 亚洲精品xxxx| 欧美体内谢she精2性欧美| 色婷婷久久av| 亚洲综合精品一区二区| 久久天天躁狠狠躁夜夜躁2014| 91久久久国产精品| 欧美激情二区三区| 欧美成人精品不卡视频在线观看| 性色av香蕉一区二区| 中文字幕日韩在线播放| 国产精品69精品一区二区三区| 国产美女被下药99| 欧美日韩成人精品| 国产精品欧美亚洲777777| 亚洲加勒比久久88色综合| 国产精品久久久久77777| 午夜精品久久久久久久久久久久| 亚洲天堂成人在线| 在线视频日韩精品| 日韩精品中文字幕有码专区| 国产精品一区二区三区免费视频| 久久久亚洲成人| 日韩亚洲国产中文字幕| 18久久久久久| 久久69精品久久久久久久电影好| 91在线观看免费高清完整版在线观看| 国产精品视频一区国模私拍| 88国产精品欧美一区二区三区| 中文字幕日韩欧美精品在线观看| 日韩国产精品视频| 欧美精品制服第一页| 国产亚洲精品久久久久久牛牛| 国产精品日韩欧美综合| 亚洲欧美中文在线视频| 91成人在线播放| 97在线观看免费高清| 日韩欧美综合在线视频| 中文国产成人精品久久一| 亚洲成色999久久网站| 日韩欧美999| 日韩精品久久久久久福利| 欧美大尺度激情区在线播放| 欧美巨猛xxxx猛交黑人97人| 日韩精品黄色网| 亚洲高清一区二| 国内精品国产三级国产在线专| 中文字幕久热精品在线视频| 深夜福利亚洲导航| 91精品久久久久久久久久久久久久| 久久久电影免费观看完整版| 久久精品国产成人| 18久久久久久| 91精品视频在线播放| 91精品美女在线| 亚洲图片在线综合| 欧美一级淫片videoshd| 中文字幕在线精品| 国产91精品最新在线播放| 6080yy精品一区二区三区| 亚洲社区在线观看| 久久午夜a级毛片| 中文字幕亚洲精品| 欧美日产国产成人免费图片| 国产小视频国产精品| 91久久嫩草影院一区二区| 91精品中国老女人| 久久久亚洲福利精品午夜| 96精品视频在线| 欧美午夜片欧美片在线观看| 国产精品亚洲аv天堂网| 尤物精品国产第一福利三区| 中国人与牲禽动交精品| 亚洲欧美日本伦理| 亚洲精品视频免费| 中文字幕精品网| 日本亚洲欧洲色| 一个人看的www久久| 日韩欧美亚洲综合| 久久理论片午夜琪琪电影网| 日韩精品视频在线观看免费| 亚洲视频国产视频| 日韩h在线观看| 中文字幕免费国产精品| 国产一区二区视频在线观看| 久久亚洲国产成人| 国产综合福利在线| 亚洲最新av在线| 最近中文字幕mv在线一区二区三区四区| 国产精品免费视频xxxx| 国产自产女人91一区在线观看| 日韩视频精品在线| 精品视频在线观看日韩| 亚洲精品久久久久国产|