從這一篇開始,就來開始咱們的make things move之旅吧css
在此以前,要知道ActionScript(AS)的語法和JS是不同的,AS是相對於JS而言更好的支持了面向對象的特性,因此咱們能夠本身實現一些簡單的工具類,讓咱們更快速的構建咱們的工程。不過咱們不用所有實現AS中的東西,咱們只用實現最基本的類的構造,類的繼承和其餘一些實用的工具函數就行了。html
其實我還想說的是,咱們仍是要實現AS的Sprite類和stage,由於這兩個東西是實現AS動畫最基本的元素,html5 canvas提供的js api仍是比較低級的,咱們能夠簡單的封裝一下實現AS的sprite 和stage,不過這兩個東西仍是等後續講有關動畫的原理再來細說吧。另外,其實如今已經有不少開源的HTML5遊戲框架,能夠直接使用,並且已經很成熟社區也好,好比如今很火的cocos2d-html5,我不是很同意本身造輪子寫一個,不過若是是出於學習目的仍是能夠一試的,由於這樣也比較容易理解框架底層的東西,和提升你的JS水平。話題跑遠了……html5
文件目錄結構java
推薦模仿linux的文件結構吧,隨便在哪放你的工程python
建立一個/mtm的文件夾,此文件夾的根目錄下: |-- index.html |-- /css |-- /js |-- /bin 此目錄旋轉最終的用於執行的js文件 |-- /lib 放置庫工具 |-- /etc 放置配置文件 |-- /mtm make things move 工程的主要例子的實現類
工具方法linux
一在js/lib/目錄下建立一個sys.js的文件json
而後實現咱們的第一個構造類的工具方法:__class__。我寫多了python,深受python類構造模式的影響(一樣的我也不分號黨,只有在寫java或其餘靜態語言的時候),雙下劃線是表示系統內置屬性或方法的意思,這只是我本身的習慣,讀者能夠根據本身的習慣來寫,不過建議有一個好的規範,個人在JS裏就不算是什麼好的。讀者也可本身實現一個可構造類並能實現繼承的方法,個人實現以下:canvas
// 參數不定,最後一個參數必須是實現的方法的json,前面的都是要繼承的類
// opts中的__init__方法則爲新類的構造函數
// example: var NewClass = __class__(Class1, Class2, {__init__: function () {}, })
this.__class__ = function (/*Class1, Class2,..., opts*/) { var args = Array.prototype.slice.call(arguments), opts if (typeof args[args.length - 1] === 'function') opts = {} else opts = args.pop() var clss = opts.__init__ || function () {}, name = opts.__name__ || __filename__(__file__()) //獲取當前js文件的名稱做爲這個類的類名,也可在opts中定義__name__ for (var i = 0, parent; parent = args[i]; i++) __copy__(parent.prototype, clss.prototype) __copy__(opts, clss.prototype) clss.__name__ = clss.prototype.__name__ = name return clss }
上面的方法中用到了幾個新的工具方法:api
1. __file__ 獲取當前文件路徑數組
2. __filename__ 獲取指定文件路徑的文件名(已去掉後綴)
3. __copy__ 簡單的拷貝屬性的方法
這些方法都在sys.js實現:
this.__copy__ = function (source, target) { for (var k in source) target[k] = source[k] return target } this.__file__ = function () { var e = document.getElementsByTagName('script') return e.length ? e[e.length - 1].src : '' }
// 獲取當前文件所在的目錄 this.__dirname__ = function (s) { var p = s.lastIndexOf('/') if (p === 0) return '/' if (p === -1) return '' return s.slice(0, p) }
// 獲取指定文件路徑的文件名字(帶後綴) this.__basename__ = function (s) { var res = s.match(/\/([^\/]+\.\w+)$/i) return res ? res[1] : '' } this.__filename__ = function (s) { var str = __basename__(s) return str.length ? str.slice(0, str.lastIndexOf('.')) : str }
最後還有一個__load__方法,屬於一個文件加載器,沒辦法js"還「沒有import咱們本身來實現一個
/**
* @param files {Array} 要加載的js文件的路徑數組
* @param ok {Function} 加載完成後的回調
* @example: __load__(['js/sys.js'], function () {console.log('load done!')})
*/
this.__load__ = function () { var _loaded_path = {} var _loader = function (src, fnc) { if (_loaded_path[src]) return fnc() var s = document.createElement("script") s.onload = function () { _loaded_path[src] = 1 fnc() } s.onerror = function () { throw "Error loading: " + src } s.src = src document.body.appendChild(s) } return function (files, ok) { files = files.slice() if (files.length == 0) return ok && ok() _loader(files.shift(), function () { __load__(files, ok) }) } }()
把上面的代碼都放到js/lib/sys.js文件中,就基本完成咱們的的工具準備了,咱們來試試使用上面的方法,順便熟悉咱們的文件 結構,在 js/mtm/ 文件夾下建立一個Test.js文件,在這裏咱們用咱們的工具函數建立咱們的第一個類:
var Test = __class__({ __init__: function () { this.sayMyName() }, sayMyName: function () { alert("I am a Class, my name is " + this.__name__) } })
再寫一個繼承類,和Test.js同目錄下建立OtherTest.js(注意,咱們的__class__方法是能夠多重繼續的,只是新類裏沒有可間接從本身類裏調用父類的方法):
var OtherTest = __class__(Test, { __init__: function () { // 手動調用父類的構造方法 Test.call(this) }, sayMyName: function () { // 手動調用父類的sayMyName方法 Test.prototype.sayMyName.call(this) // 再彈出一個信息 alert("All done!") } })
類是寫完了,但咱們並無引用,咱們來部署一下咱們測試環境:在js/etc/ 目錄下建立一個mtm_module.js的文件,裏面把咱們js/mtm/文件裏的js路徑都寫入一個mtm_module數組中:
var mtm_module = [ 'js/mtm/Test.js',
'js/mtm/OtherTest.js',
]
之後都把mtm文件的路徑往這個數組裏加。在js/lib/目錄下建立一個main.js的最終執行文件,而後主要就是在這個文件中加載其餘js 執行測試代碼:
// 把js/mtm/裏的測試類都加載進來 __load__(mtm_module, function () { // 實例化一個Test類 var test = new Test() })
最後就是寫index.html頁面,把主要的sys.js,mtm_module.js, main.js用標籤引入就OK了:
<!doctype html> <html> <head> <title> Make things move </title> </head> <body> <script src='js/lib/sys.js'></script> <script src='js/etc/mtm_module.js'></script> <script src='js/bin/main.js'></script> </body> </html>
到此,若是過程都沒有任何問題,你能夠打開index.html 而後就會彈出咱們上面寫的信息!若是你用的是mac 或 linux系統建議直接用命令行工具在該工程根目錄輸入`python -m SimpleHTTPServer 8000` 而後瀏覽器上打開localhost:8000就能看到效果了。寫了這麼多,可能篇幅有些長,下次寫看來要控制一下 :p