首頁  >  文章  >  web前端  >  javascript製作坦克大戰全紀錄(1)_javascript技巧

javascript製作坦克大戰全紀錄(1)_javascript技巧

WBOY
WBOY原創
2016-05-16 16:30:051685瀏覽

PS:這場戰車大戰是在網路下的一段源碼之後,自己進行的重寫。本身沒有太難的東西,這個案例將js物件導向的比較好,可以作為js物件導向的入門教學。

1.   建立基本對象,實現坦克簡單的移動

1.1    如何在地圖中繪製畫布

    考慮到瀏覽器相容的問題,我們用操作dom的方式來實現遊戲物件的繪製和刷新。我們如何儲存我們的地圖呢? 我們應該把地圖用一個二維數組來保存, js中沒有二維數組,但是可以透過在一維數組從儲存數組來實現。

1.2    程式碼實作

    我們將畫布設計為13 * 13 的一個二維數組,每個元素在地圖中對應的長和寬均為40px,可以把整個地圖看成由40px*40p x大小的單元格組成的一個表格,那麼我們整個畫布的大小為520px  *  520px ;
 
   上程式碼前先給大家來一張物件關係圖:

1.2.1    建立頂層物件

html代碼:

複製程式碼 程式碼如下:

 
 
 
     戰車大戰
    
    
    
    
    
    
     <script><br />          window.onload = function () {<br />              // 呼叫遊戲裝載​​者<br />              var loader = new GameLoader();<br />              loader.Begin();<br />          }<br />      </script>
 
 
 
    
    

    

    

    

 
 

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

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

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn