1. 程式人生 > >【javascript面向物件之路】讓我們一起來坦克大戰吧01

【javascript面向物件之路】讓我們一起來坦克大戰吧01

提問

不知道大家發現沒有,執行時候瀏覽器或者電腦會變得很卡哦。根據我們之前的學習,你知道是什麼原因導致的嗎?

若是各位有興趣,請你回答卡的原因,並提出優化方案。 

前言

PS 各位要看效果還是使用ff或者google吧,ie7以下好像有問題。

最近大家都在坦克大戰,我突然想了下我是不是也應該坦克大戰一番呢?於是,我們就有了今天的東西。

其實做坦克大戰並不是為了坦克大戰,而是為了javascript面向物件!所以我這裡並不會完成這個遊戲,做到哪步是哪步吧。

怎麼說呢?javascript面向物件大家都聽得很多了,但能真正理解的人並不多,我事實上也是水的,知道一點皮毛是沒用的,所以想以此提升面向物件的思想。

PS:最近其實事情挺多的,HTML5+CSS3、CSS、javascript、bootstrap、響應式佈局......我現在是想到哪打哪啊!

算了,扯遠了,我們開始今天的學習吧。

PS:執行的時候請使用高版本瀏覽器,這裡暫時沒有做瀏覽器相容

工欲善其事必先利其器

剛開始幹我就在想,我是不是該寫個類庫神馬的,於是在這裡磨磨蹭蹭的搞了一個多小時,硬是擠出了以下程式碼:

 1 function getById(id) {
 2     return !id ? null : document.getElementById(id);
 3 }
 4 
 5 function getAttr(el, k) {
6 if (el) { 7 var v = el.getAttribute[k] ? el.getAttribute[k] : null; 8 return v; 9 } 10 } 11 12 function setAttr(el, k, v) { 13 if (el) { 14 el.setAttribute(k, v); 15 } 16 } 17 18 function getCss(el, k) { 19 if (el) { 20 21 if
(el.style[k]) { 22 return el.style[k]; 23 } 24 return null; 25 } 26 } 27 28 function setCss(el, k, v) { 29 if (el) { 30 if (!el.style || el.style.length == 0) { 31 el.style = {}; 32 } 33 el.style[k] = v; 34 } 35 }

不用看,也不用說,光是想求得元素的樣式這塊我就知道有問題,但是我們不能捨本逐末,這裡暫時不管他(因為我搞了個把小時了),我們還是按著邏輯往下走吧。

資料準備

我們這裡需要一點點坦克的圖片,於是開啟我們的PS,PS之:

這個坦克的資源,我不知道原來從哪裡來的,這裡先私自用了,原作者若是覺得有問題請留言。

PS:我們這裡先不考慮小圖示的問題,一點點來吧

首先是我們的子彈爆炸要用到的圖片:

看到這個圖片各位就應該要想到炮彈爆炸式怎麼實現的了哦!

然後我們的主角,坦克的圖片:

下面是我們的子彈:

於是我們幾個坦克也有了,子彈也有了,好了我們先不關注其它,看看我們能不能把坦克給搞出來(話說我PS不是太好,這個也必須納入必學範圍)。

移動的坦克

我們搞移動的坦克之前,在頁面上先弄一張地圖,作為坦克使用:

 1 <html xmlns="http://www.w3.org/1999/xhtml">
 2 <head>
 3     <title></title>
 4     <style type="text/css">
 5         .map { background: gray; border: 1px solid black; position: relative; margin: 50px auto; width: 416px; height: 416px; }
 6     </style>
 7 </head>
 8 <body>
 9     <div class="map" id="map">
10         <div id="me" class="tank">
11         </div>
12     </div>
13 </body>
14 </html>

好了,讓我們主角坦克登場吧,注意其中的me:

 1 <html xmlns="http://www.w3.org/1999/xhtml">
 2 <head>
 3     <title></title>
 4     <style type="text/css">
 5         .map { background: gray; border: 1px solid black; position: relative; margin: 50px auto; width: 416px; height: 416px; }
 6          .tank { background-image: url("images/tank.gif"); overflow: hidden; position: absolute; width: 32px; height: 32px; z-index: 3; }
 7          
 8     </style>
 9 </head>
10 <body>
11     <div class="map" id="map">
12         <div id="me" class="tank">
13         </div>
14     </div>
15 </body>
16 </html>

我們可愛的坦克,還是2二級的坦克出現啦,現在我們為他加上移動效果,這裡就要開始寫程式碼啦,首先我們定義一個坦克類:

 1 var Tank = function (id, dir, x, y) {
 2     this.el = getById(id);
 3     this.direction = dir ? dir : 'up';
 4     this.tid = null;
 5     this.speed = 10;
 6     //坦克活動狀態 0 未活動 1 正在活動
 7     this.activeState = 0;
 8     this.x = x ? x : 100;
 9     this.y = y ? y : 200;
10     this.dirState = {
11         up: 1,
12         right: 1,
13         down: 1,
14         left: 1
15     };
16 }

我現在能想到坦克具有的屬性便是:

1 坦克對應的html標籤

2 坦克的初始化方向

3 坦克的初始化位置

在修改一點點,我們就能控制坦克轉向了:

  1 <html xmlns="http://www.w3.org/1999/xhtml">
  2 <head>
  3     <title></title>
  4     <style type="text/css">
  5         .map { background: gray; border: 1px solid black; position: relative; margin: 50px auto; width: 416px; height: 416px; }
  6          .tank { background-image: url("images/tank.gif"); background-repeat: no-repeat; overflow: hidden; position: absolute; width: 32px; height: 32px; z-index: 3; }
  7     </style>
  8 </head>
  9 <body>
 10     <div class="map" id="map">
 11         <div id="me" class="tank">
 12         </div>
 13     </div>
 14 
 15     <script src="../06tank/js/core.js" type="text/javascript"></script>
 16     <script type="text/javascript">
 17         var Tank = function (id, dir, x, y) {
 18             this.el = getById(id);
 19             this.direction = dir ? dir : 'up';
 20             this.tid = null;
 21             this.speed = 10;
 22             //坦克活動狀態 0 未活動 1 正在活動
 23             this.activeState = 0;
 24             this.x = x ? x : 100;
 25             this.y = y ? y : 200;
 26             this.dirState = {
 27                 up: 1,
 28                 right: 1,
 29                 down: 1,
 30                 left: 1
 31             };
 32         };
 33         Tank.prototype.init = function () {
 34             var dir = this.direction;
 35             var tank = this.el;
 36             setCss(tank, 'left', this.x + 'px');
 37             setCss(tank, 'top', this.y + 'px');
 38             this.setDirection(dir);
 39         };
 40         Tank.prototype.setDirection = function (dir) {
 41             var tank = this.el;
 42             if (dir == 'up') {
 43                 setCss(tank, 'backgroundPosition', '0 0');
 44             }
 45             if (dir == 'right') {
 46                 setCss(tank, 'backgroundPosition', '-5px -36px');
 47             }
 48             if (dir == 'down') {
 49                 setCss(tank, 'backgroundPosition', '0 -73px');
 50             }
 51             if (dir == 'left') {
 52                 setCss(tank, 'backgroundPosition', '0 -105px');
 53             }
 54             this.dirState[dir] = 1;
 55         };
 56 
 57         var tank = new Tank('me', 'right', 100, 100);
 58         tank.init();
 59 
 60         function getDir(code) {
 61             if (code == '87' || code == '119') {
 62                 return 'up';
 63             }
 64             if (code == '100' || code == '68') {
 65                 return 'right';
 66             }
 67             if (code == '115' || code == '83') {
 68                 return 'down';
 69             }
 70             if (code == '97' || code == '65') {
 71                 return 'left';
 72             }
 73             return null;
 74         }
 75 
 76         document.onkeydown = function (evt) {
 77             evt = (evt) ? evt : window.event;
 78             var keyCode = evt.keyCode;
 79             var charCode = evt.charCode;
 80             var dir = getDir();
 81             if (keyCode) {
 82                 dir = getDir(keyCode.toString());
 83             }
 84             if (charCode) {
 85                 dir = getDir(charCode.toString());
 86             }
 87             tank.setDirection(dir);
 88 
 89             evt.preventDefault();
 90             return false;
 91         };
 92         document.onkeyup = function (evt) {
 93         };
 94         document.onkeypress = function (evt) {
 95             evt = (evt) ? evt : window.event;
 96             var keyCode = evt.keyCode;
 97             var charCode = evt.charCode;
 98             var dir = getDir();
 99             if (keyCode) {
100                 dir = getDir(keyCode.toString());
101             }
102             if (charCode) {
103                 dir = getDir(charCode.toString());
104             }
105             evt.preventDefault();
106             return false;
107         };
108     </script>
109 </body>
110 </html>
View Code

執行效果(此處可執行):

然後我們來加上移動的動畫,各位注意啦,我們這裡要使用js實現動畫啦!我們來看看這段程式碼:

  1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4     <title></title>
  5     <style type="text/css">
  6         .map { background: gray; border: 1px solid black; position: relative; margin: 50px auto; width: 416px; height: 416px; }
  7         .tank { background-image: url("http://images.cnitblog.com/blog/294743/201306/12123133-eaa9ada8690e4216a2bee3e56442e032.gif"); background-repeat: no-repeat; overflow: hidden; position: absolute; width: 32px; height: 32px; z-index: 3; }
  8     </style>
  9 </head>
 10 <body>
 11     <div class="map" id="map">
 12         <div id="me" class="tank">
 13         </div>
 14     </div>
 15     <script type="text/javascript">
 16         function getById(id) {
 17             return !id ? null : document.getElementById(id);
 18         }
 19 
 20         function getAttr(el, k) {
 21             if (el) {
 22                 var v = el.getAttribute[k] ? el.getAttribute[k] : null;
 23                 return v;
 24             }
 25         }
 26 
 27         function setAttr(el, k, v) {
 28             if (el) {
 29                 el.setAttribute(k, v);
 30             }
 31         }
 32 
 33         function getCss(el, k) {
 34             if (el) {
 35 
 36                 if (el.style[k]) {
 37                     return el.style[k];
 38                 }
 39                 return null;
 40             }
 41         }
 42 
 43         function setCss(el, k, v) {
 44             if (el) {
 45                 if (!el.style || el.style.length == 0) {
 46                     el.style = {};
 47                 }
 48                 el.style[k] = v;
 49             }
 50         }
 51 
 52         var MyGlobal = {
 53             mapWidth: 416,
 54             mapHeight: 416,
 55             width: 448,
 56             height: 512
 57         };
 58 
 59         var Tank = function (id, dir, x, y) {
 60             this.el = getById(id);
 61             this.direction = dir ? dir : 'up';
 62             this.tid = null;
 63             this.speed = 10;
 64             //坦克活動狀態 0 未活動 1 正在活動
 65             this.activeState = 0;
 66             this.x = x ? x : 100;
 67             this.y = y ? y : 200;
 68             this.dirState = {
 69                 up: 1,
 70                 right: 1,
 71                 down: 1,
 72                 left: 1
 73             };
 74         };
 75         Tank.prototype.init = function () {
 76             var dir = this.direction;
 77             var tank = this.el;
 78             setCss(tank, 'left', this.x + 'px');
 79             setCss(tank, 'top', this.y + 'px');
 80             this.setDirection(dir);
 81         };
 82         Tank.prototype.setDirection = function (dir) {
 83             var tank = this.el;
 84             if (dir == 'up') {
 85                 setCss(tank, 'backgroundPosition', '0 0');
 86             }
 87             if (dir == 'right') {
 88                 setCss(tank, 'backgroundPosition', '-5px -36px');
 89             }
 90             if (dir == 'down') {
 91                 setCss(tank, 'backgroundPosition', '0 -73px');
 92             }
 93             if
            
           

相關推薦

javascript面向物件我們起來坦克大戰01

提問 不知道大家發現沒有,執行時候瀏覽器或者電腦會變得很卡哦。根據我們之前的學習,你知道是什麼原因導致的嗎? 若是各位有興趣,請你回答卡的原因,並提出優化方案。  前言 PS 各位要看效果還是使用ff或者google吧,ie7以下好像有問題。 最近大家都在坦克大戰,

javascript 面向物件.2 - 小蜜蜂

接著上篇文章繼續. 要實現上篇中gif圖片的效果, 我們要寫js, 演算法並不是很複雜, 本次也僅僅展示了實現功能的程式碼, 並沒有從面向物件的角度去構思或重構程式碼. 這裡, 我們定義了一些變數, 用來定義圖形介面各個元素的尺寸以及其他引數. 實現的功能就是捕獲使用者的鍵盤事件, 39.37代表了

javascript 面向物件.1 - 小蜜蜂

寫這個系列文章是想通過幾個案例來學習javascript html5 css3,其實這個小遊戲誰都能做出來,但對於一個作為後端.net程式設計師的我來說還是有學習的必要,畢竟javascript的面向物件跟C# 截然不同,在接觸javascript時,第一個感覺就是太靈活了,這是弱型別語言的弊端也是優勢,靈活

SSH進階Hibernate映射——一對一單向關聯映射(五)

技術 iyu 標識 tails for sso 3.0 sdn 例如 【SSH進階之路】Hibernate基本原理(一) ,小編介紹了Hibernate的基本原理以及它的核心,採用對象化的思維操作關系型數據庫。 【SSH進階之路】Hibernate搭建開發環境+簡單實例

SSH進階Struts + Spring + Hibernate 進階開端(

height 一段 ioc 效率 陽光大道 面向對象的思想 text ase 們的 Long Long ago。就聽說過SSH。起初還以為是一個東東,詳細內容更是不詳,總認為高端大氣上檔次,經過學習之後才發現,不不過高大上,更是低調奢華有內涵,經過一段時間的

SSH進階Hibernate基本映射(三)

tor res 主動 tran clas oid 支持包 lose 包括 【SSH進階之路】Hibernate基本原理(一) ,小編介紹了Hibernate的基本原理以及它的核心。採用對象化的思維操作關系型數據庫。 【SSH進階之路】Hibernate搭建開發環境+簡單

SSH進階Struts基本原理 + 實現簡單登錄(二)

target doctype 掌握 pack insert enter snippet file manage 上面博文,主要簡單的介紹了一下SSH的基本概念,比較宏觀。作為剛開始學習的人可以有一個總體上的認識,個人覺得對學習有非常好的輔助功能,它不不過

JavaScript 面向物件二 —— 函式上下文(call() 和 apply())

本系列文章根據《愛前端邵山歡老師深入淺出的js面向物件》視訊整理歸納 call() 和 apply() 這兩個都是函式的方法,只有函式能夠通過點方法呼叫call()、apply(),表示用指定的上下文執行這個函式。 如下,定義一個函式 fun,當 fun 函式裡

JavaScript 面向物件二 —— 函式上下文(this的指向)

本系列文章根據《愛前端邵山歡老師深入淺出的js面向物件》視訊整理歸納 函式上下文 在 JavaScript 中,函式的上下文是有規律可循的,基本可以分為以下幾項: 規律一:函式用圓括號呼叫,函式上下文是 window 物件。 如下,函式 function f

SSH進階Hibernate基本對映(三)

【SSH進階之路】Hibernate基本原理(一) ,小編介紹了Hibernate的基本原理以及它的核心,採用物件化的思維操作關係型資料庫。 【SSH進階之路】Hibernate搭建開發環境+簡單例項

SSH進階Hibernate基本原理(

      在開始學Hibernate之前,一直就有人說:Hibernate並不難,無非是對JDBC進一步封裝。一句不難,難道是真的不難還是眼高手低?       如果只是停留在使用的層面上,我相信什

JavaScript面向物件繼承 (上)

原型鏈繼承 我們再通過前幾篇的例子再瞭解下原型鏈繼承 //建立自定義建構函式 function Person() { this.name = "姓名"; } //在當前建構函式的原型鏈上新增屬性hobby Person.prototype.hobby = "旅遊" //

JavaScript面向物件繼承(下)

原型式繼承 這種繼承方式沒有使用嚴格意義上的建構函式,藉助原型還可以基於已有的物件建立新物件,同時還不必因此建立自定義型別 function object(o) { function Fun() {} Fun.prototype = o; return n

探索docker儲存三、docker中的映象儲存與Overlayfs

docker中的映象儲存 docker中映象的概念其實就是一組只讀目錄。每一個目錄是一個layer,多個layer按照一定的順序組成一個stack。在容器建立時,docker增加在stack之上一個thin和writable layer,如下圖 基

1>test.obj : error LNK2005: _main 已經在 main.obj 中定義c的學習

下決心要在空餘時間學習C語言,從今天開始。 遇到的一個小問題,查詢資料結果如下。 造成LNK2005錯誤主要有以下幾種情況: 1.重複定義全域性變數。可能存在兩種情況: A、對於一些初學程式設計的程式設計師,有時候會以為需要使用全域性變數的地方就可

探索docker儲存、窺探docker中的volume plugin內幕

重構前言 本來想後續一篇文章專門寫docker volume plugin。這篇可以簡單粗暴的拉通docker的程式碼。之前看《Docker容器和容器雲》感覺原理解析部分沒有進一步深入到volume plugin的層次。本想以此作為第3篇的主要內容。最近看了一下新出

GOF設計模式-- Factory

自從開始工作,就感覺精力相比在大學時有很大幅度的下降。大二那一年精力最旺盛,自從大二結束開始工作到現在,兩年時間,似乎精力都已經不受自己控制了。如果對一些技術研究工作不是很感興趣,下班之後基本上到晚上10點左右就想睡覺。工作兩年加上大二的一年,一直到現在都堅持每天必須有新的

SSH進階Struts基本原理 + 實現簡單登入(二)

      上面博文,主要簡單的介紹了一下SSH的基本概念,比較巨集觀,作為初學者能夠有一個整體上的認識,個人認為對學習有很好的輔助功能,它不僅僅是一個“瞭望塔”,更是檢驗是否真正掌握所有內容的一個前

SSH進階Hibernate對映——多對單向關聯對映(四)

【SSH進階之路】Hibernate基本原理(一) ,小編介紹了Hibernate的基本原理以及它的核心,採用物件化的思維操作關係型資料庫。 【SSH進階之路】Hibernate搭建開發環境+簡單例項

SSH進階Spring的IOC逐層深入——依賴注入的兩種實現型別(四)

        上篇博文,我們介紹了為什麼使用IOC容器,和IOC的設計思想以及IOC容器的優缺點,並且給大家轉載了一篇介紹IOC原理的博文,我們這篇主要給大家依賴注入的兩種方式,以及他們的優缺點。