搜尋
首頁web前端js教程javascript製作坦克大戰全紀錄(1)_javascript技巧

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
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器