ejoy2d源碼閱讀筆記1

一直想學lua,學它如何與C結合來做邏輯,因此找了雲風的一份代碼來研究。這份代碼是個框架庫,叫ejoy2d,據雲風的博客說,他們最新的手機遊戲用的就是這套框架,因此實用性應該很強,雖然我不是學遊戲的,但應該也能學習到不少。
話很少說,開始看源碼。html

框架支持windows, linux, ios三種環境,這裏只看windows的,用的是mingw。linux

程序入口main在 window.c:ios

  1. 建立窗口
  2. ejoy2d_win_init 用來初始化ejoy2d
  3. 進行windows消息循環

ejoy2d_win_init定義在winfw.c中,一共就下面這幾步:git

  1. create_game 初始ejoy2d引擎
  2. 加載初始化腳本 startscript
  3. lua_pcall這裏調用了一下,調的哪一個函數下面說
  4. screen_init
  5. ejoy2d_game_start

先看看create_game到底作了啥:github

  1. 建立lua_State
  2. 打開一堆庫,包括了全部的ejoy2d的庫
  3. shader_init 初始化shader環境
  4. label_load 加載字體(不知道爲啥字體叫label。。。回頭細看)

再看看加載的 startscript 是個啥:windows

 
 
 
 
local path, script = ...require("ejoy2d.framework").WorkDir = ''assert(script, 'I need a script name')path = string.match(path,[[(.*)\[^\]*$]])package.path = path .. [[\?.lua;]] .. path .. [[\?\init.lua;.\?.lua;.\?\init.lua]]local f = assert(loadfile(script))f(script)

由於最後生成的ej2d.exe調用時是 ej2d.exe xxx.lua,因此根據上面的代碼,那麼path中就會保存ej2d.exe的所在路徑,而script則保存xxx.lua,因此上面這段腳本最後會設置package的搜索路徑(這裏爲後面自定義腳本加載ejoy2d的lua庫作好鋪墊),同時執行給定的腳本。框架

看到這裏,應該能明白上面第3步裏其實就是執行的這段腳本,至於爲啥不用dofile來加載startscript,是想在這裏打印錯誤信息的緣由。函數

行,到這兒create_game看完了,再回到ejoy2d_win_init接着往下看。學習

screen_init,代碼裏很簡單,就是初始化好opengl的viewport。字體

ejoy2d_game_start這個函數看代碼,應該是依次調了 EJOY_INITEJOY2D_UPDATEEJOY2D_DRAWFRAME這三個函數,不過這裏用到了LUA_REGISTRYINDEX這個東西,lua我不熟,因此看看PIL後又結合網上其餘人的說法,這是lua的「註冊表」,這個東西其實也是一張表,可是一張全局的表,能夠經過僞索引來搜索,貌似是比其餘的方式快?

好的,問題來了:挖掘機技術哪家。。。打住,不是這個,而是EJOY_INITEJOY2D_UPDATEEJOY2D_DRAWFRAME這三個函數是從哪兒來的,源碼裏沒有找到對應的實現,沒辦法,只能看看example了。

略過 examples/ex01.lua 前面的一堆代碼,咱們看到這個:

 
 
 
 
local game = {}function game.update()endfunction game.drawframe() -- use shader.draw to draw a polygon to screen (for debug use) shader.draw(TEXID, { 88, 0, 88, 45, 147, 45, 147, 0, -- texture coord -958, -580, -958, 860, 918, 860, 918, -580, -- screen coord, 16x pixel, (0,0) is the center of screen })endfunction game.touch(what, x, y)endej.start(game)

這裏定義了一個game對象,實現了三個方法:update, drawframe, touch,最後做爲參數傳入了ej.start裏。等等,前兩個函數好像跟上面的有關係。看看ej.start(game)都幹了些什麼。

打開 ejoy2d/init.lua:

 
 
 
 
function fw.EJOY2D_INIT() shader.init()endfunction ejoy2d.start(callback) fw.EJOY2D_UPDATE = assert(callback.update) fw.EJOY2D_DRAWFRAME = assert(callback.drawframe) fw.EJOY2D_TOUCH = function(x,y,what,id) return callback.touch(touch[what],x,y,id) end fw.EJOY2D_GESTURE = function(what, x1, y1, x2, y2, state) return callback.gesture(gesture[what], x1, y1, x2, y2, state) end fw.inject()end

哈,這裏把剛纔game中定義的三個方法都放到對應的EJOY2D_XX裏了,同時調用inject函數,完成了lua函數的注入。此時再回到ejoy2d_game_start中,一切合理了。



相關文章
相關標籤/搜索