本系列文章由Shin-Knight編寫,轉載需註明出處。html
做者:Shin-Knighthtml5
郵箱:shinknight@163.comjson
文章連接:http://www.cnblogs.com/knightls/p/3281387.htmlcanvas
在筆記一中,咱們對html5遊戲開發作了一個總的概述,接下來就該輪到實現功能的時候了。在上一章中也提到過,圖片是遊戲中不可缺乏的一部分,所以咱們今天就先來實現一下。app
首先,我以爲能夠先講一講本次開發的原理和設計方案:函數
爲了方便之後實現層次化效果,咱們能夠採用繪畫的前後順序來實現。可是若是說咱們有兩個層:A和B,以下圖放置:測試
假設咱們先畫了B層,而後再畫了A層。接着,咱們往B層上添加個C層,這時候,若是仍是將C層直接畫在界面上,顯示是在A層上,而不是B層上,所以,咱們須要不斷地重畫這個界面。將A層,B層,C層加到顯示列表中,經過遍歷這個列表進行顯示。固然,這是之後涉及到層次化效果的時候要使用的,如今講講只是爲了理解本文中,我採起重繪界面作法的意義。this
因爲本次開發涉及到封裝,因此暫時給這個項目取名爲Tomato2D吧,哈哈。 名字是隨便想的,之後或許還會改。spa
有一些全局的變量和函數爲了使用起來不重複,所以定義了一個TGlobalVar靜態類,它負責裝一些全局變量和函數,以避免使用的時候和其餘的變量相同。以下:prototype
1 var TGlobalVar = function(){this.type = "TGlobalVar";};
這個之後若是有其餘變量加入的話,會慢慢拓展。接下來爲了使界面結構更清晰咱們還要創建一個TMainWindow和TApplication類。負責全局的驅動和存儲一些全局數據。
先看TMainWindow的代碼:
1 function TMainWindow(data){ 2 var self = this; 3 4 self.type = "TMainWindow"; 5 6 self.childList = new Array(); 7 self.width = data.width || 200; 8 self.height = data.height || 120; 9 TGlobalVar.TApplicationObj.id = data.id; 10 TGlobalVar.TApplicationObj.frameRate = data.frameRate; 11 } 12 TMainWindow.prototype.init = function(){ 13 var self = this; 14 15 if(TGlobalVar.isAddMainWindow == true)return; 16 TGlobalVar.TMainWindowObj = self; 17 TGlobalVar.isAddMainWindow = true; 18 var w = self.width; 19 var h = self.height; 20 TGlobalVar.TApplicationObj.canvasObj = document.getElementById(TGlobalVar.TApplicationObj.id); 21 TGlobalVar.TApplicationObj.canvasObj.width = w; 22 TGlobalVar.TApplicationObj.canvasObj.height = h; 23 }; 24 TMainWindow.prototype.onShow = function(){ 25 var self = this; 26 if(TGlobalVar.TApplicationObj.canvas == null)return; 27 TGlobalVar.TApplicationObj.canvas.clearRect(0,0,TGlobalVar.TApplicationObj.width,TGlobalVar.TApplicationObj.height); 28 self.show(self.childList); 29 }; 30 TMainWindow.prototype.show = function(showlist,cood){ 31 if(cood == null)cood={x:0,y:0}; 32 var key = null; 33 for(key in showlist){ 34 if(showlist[key].show){ 35 showlist[key].show(cood); 36 } 37 } 38 };
這個類實例化的時候有一個參數,是一個json對象,格式以下:
1 { 2 id:canvas的id, 3 width:canvas的寬, 4 height:canvas的高, 5 frameRate:刷新頻率 6 }
而後調用TMainWindow的init時,會自動保存這些數據,在其中用到了TGlobalVar.isAddMainWindow,TGlobalVar.TMainWindowObj,TGlobalVar.TApplicationObj這幾個變量,其中TGlobalVar.isAddMainWindow是用來判斷是否已經init過TMainWindow,由於界面上不可能有兩個TMainWindow,因此用這個加以限制,而TGlobalVar.TMainWindowObj是用來保存界面上TMainWindow的變量,TGlobalVar.TApplicationObj是用來保存界面上TApplication對象的變量。
在TMainWindow類中,還有個onShow和show方法,這兩個方法是用來刷新界面用的。onShow是負責清空界面和調用show方法用的。在show方法中經過遍歷TMainWindow裏的childList,調用遍歷到的元素的show方法,實現重繪,也就是說,在childList裏的元素必須有show方法才行。onShow方法在TApplication中會用到。
具體TApplication裏的代碼以下:
1 function TApplication(){ 2 var self = this; 3 self.type = "TApplication"; 4 self.canvas = null; 5 self.canvasObj = null; 6 self.frameRate = 50; 7 self.objectIndex = 0; 8 self.id = null; 9 self.driver = null; 10 11 TGlobalVar.TApplicationObj = self; 12 } 13 TApplication.prototype.exec = function(){ 14 var self = this; 15 16 if(TGlobalVar.isAddApplication == true)return; 17 TGlobalVar.isAddApplication = true; 18 self.canvas = self.canvasObj.getContext("2d"); 19 self.driver = setInterval(function(){TGlobalVar.TMainWindowObj.onShow();},self.frameRate); 20 };
這個類應該是在TMainWindow前實例化,不然就會報錯。可是在調用成員函數exec時,要在TMainWindow對象調用init以後調用。這個exec至關因而一個開啓遊戲重畫的函數,也就是說,不調用這個函數界面將不能重畫。在exec中又用到了TGlobalVar.isAddApplication這個變量,它和上文的TGlobalVar.isAddMainWindow的用途差很少,只不過一個是用來判斷是否加入了TMainWindow對象,另外一個是用來判斷是否加入了TApplication對象。也就是說,咱們使用的時候只能有一個TMainWindow對象和一個TApplication對象。用TGlobalVar.TApplicationObj和TGlobalVar.TMainWindowObj分別保存TApplication和TMainWindow對象是爲了方便之後的操做。看到下面你就會明白。
由於在TGlobalVar中加了幾個成員屬性,所以修改TGlobalVar,完整TGlobalVar代碼以下:
1 var TGlobalVar = function(){this.type = "TGlobalVar";}; 2 TGlobalVar.TApplicationObj = null; 3 TGlobalVar.TMainWindowObj = null; 4 TGlobalVar.isAddApplication = false; 5 TGlobalVar.isAddMainWindow = false;
有了這些,咱們就能夠用來顯示圖片了~~
上面咱們已經把一些公有屬性都保存好了,所以咱們要實現繪畫就很簡單了。先看TImage類的代碼:
1 function TImage(){ 2 var self = this; 3 4 self.type = "TImage"; 5 self.x = 0; 6 self.y = 0; 7 self.scaleX = 1; 8 self.scaleY = 1; 9 self.isLoadComplete = false; 10 self.content = null; 11 self.sx = 0; 12 self.sy = 0; 13 self.swidth = 0; 14 self.sheight = 0; 15 self.width = 0; 16 self.height = 0; 17 self.toSwidth = self.swidth; 18 self.toSheight = self.sheight; 19 self.toSx = self.sx; 20 self.toSy = self.sy; 21 } 22 TImage.prototype.load = function(u){ 23 var self = this; 24 self.isLoadComplete = false; 25 self.content = new Image(); 26 self.content.onload = function(){ 27 self.content.onload = null; 28 self.swidth = self.content.width; 29 self.sheight = self.content.height; 30 self.width = self.content.width; 31 self.height = self.content.height; 32 self.isLoadComplete = true; 33 }; 34 self.content.src = u; 35 }; 36 TImage.prototype.draw = function(layer){ 37 var self = this; 38 if(!layer)layer = TGlobalVar.TMainWindowObj; 39 layer.childList.push(self); 40 self.parent = layer; 41 }; 42 TImage.prototype.scale = function(scaleX,scaleY){ 43 var self = this; 44 45 self.scaleX = scaleX || self.scaleX; 46 self.scaleY = scaleY || self.scaleY; 47 }; 48 TImage.prototype.move = function(x,y){ 49 var self = this; 50 51 self.x = x || self.x; 52 self.y = y || self.y; 53 }; 54 TImage.prototype.setProperties = function(sx,sy,swidth,sheight){ 55 var self = this; 56 57 self.toSwidth = swidth || self.swidth; 58 self.toSheight = sheight || self.sheight; 59 self.toSx = sx || self.sx; 60 self.toSy = sy || self.sy; 61 }; 62 TImage.prototype.show = function(){ 63 var self = this; 64 65 if(self.isLoadComplete == false)return; 66 self.swidth = self.toSwidth || self.swidth; 67 self.sheight = self.toSheight || self.swidth; 68 self.sx = self.toSx || 0; 69 self.sy = self.toSy || 0; 70 self.width = self.swidth; 71 self.height = self.sheight; 72 73 TGlobalVar.TApplicationObj.canvas.drawImage( 74 self.content, 75 self.sx,self.sy, 76 self.swidth,self.sheight, 77 self.x,self.y, 78 self.width*self.scaleX, 79 self.height*self.scaleY 80 ); 81 };
這裏面的代碼不難理解,顯示圖片的部分主要在show函數中。要加載圖片須要在load函數中加載,也就是說,要顯示圖片須要先load一遍。另外,爲了show函數並不須要本身去調用,在TGlobalVar.TMainWindowObj.show裏面已經自動調用了。不過要顯示圖片要調用draw函數,這個函數有個參數,這個參數表明顯示層,不添的話就是默認的最底層,這個參數如今只能不賦值,由於如今還沒實現到層次化這一部分。
要移動圖片的話,調用move方法就能夠了。參數:[x座標, y座標]
要設置顯示部分圖片調用setProperties就好了,參數是:[圖片可視範圍x, 圖片可視範圍y, 圖片可視範圍寬度, 圖片可視範圍高度]
要拉伸圖片就調用scale函數,參數[x軸拉伸倍數, y軸拉伸倍數]
好了,咱們有了TImage類,就來作個測試吧,測試代碼:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>顯示一張圖片</title> 6 <script src="./TMain.js"></script> 7 <script src="./TApplication.js"></script> 8 <script src="./TMainWindow.js"></script> 9 <script src="./TImage.js"></script> 10 <script> 11 function main(){ 12 var app = new TApplication(); 13 var mainwindow = new TMainWindow({ 14 id:"tomatogame", 15 width:800, 16 height:600, 17 frameRate:50 18 }); 19 mainwindow.init(); 20 app.exec(); 21 showImage(); 22 } 23 function showImage(){ 24 var img = new TImage(); 25 img.load("./face.jpg"); 26 img.draw(); 27 img.move(20,20); 28 img.scale(0.5,0.8); 29 30 var img2 = new TImage(); 31 img2.load("./face.jpg"); 32 img2.draw(); 33 img2.move(150,150); 34 img2.setProperties(100,100,200,200); 35 } 36 </script> 37 </head> 38 <body onload="main()"> 39 <canvas id="tomatogame"></canvas> 40 </body> 41 </html>
運行出來的界面以下:
over,是否是很簡單?下一次咱們來實現一下層次化效果。敬請期待~~
源代碼下載:點擊這裏下載源代碼
若是你們有不懂的地方,歡迎在文章下方留言。能看到大家的留言,是我最開心的事了~~若是文章有疏漏的地方,也歡迎指出,多謝你們的支持。