欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

lua開發(fā)中實現(xiàn)MVC框架的簡單應用

 更新時間:2015年04月10日 10:47:53   投稿:hebedich  
最近的游戲項目中使用了lua腳本來開發(fā),項目中用到了MVC框架,最近有朋友問我怎么弄,在這里簡單分享一下思路和一些開發(fā)中的技巧。有需要的小伙伴可以參考下。

       先簡單說說MVC,即Model View Controller。Model(模型),一般負責數(shù)據(jù)的處理;View(視圖),一般負責界面的顯示;Controller(控制器),一般負責前端的邏輯處理。拿一款手機游戲來說,界面UI的顯示、布局等就是View負責;點擊了按鈕,手勢的滑動等操作由Controller來處理;游戲中需要的數(shù)據(jù)資源就交給Model。

       接下來,看看在游戲開發(fā)中怎么用,這里用Lua(環(huán)境使用cocos code ide)給大家說說。

       先來看看項目的目錄結構:

        其中cocos、Controller、Model、View這個不用多說,Event里面保存的全局消息類型,Managers是用于管理游戲中的東東的,比如管理資源,管理各種場景切換,層的切換等等。Utilities提供一些工具類,比如字符串的處理等。大家也可以根據(jù)自己的需求來定制目錄,比如定義一個NetCenter文件夾,專門用于處理網(wǎng)絡的。本例子中沒有用到數(shù)據(jù)操作和工具類,所以這兩個文件夾為空。

        我們以游戲的運行流程為線索來展開說明。

        運行項目,進入到main.lua文件,來看看main函數(shù):

local function main() 
  collectgarbage("collect") 
  -- avoid memory leak 
  collectgarbage("setpause", 100) 
  collectgarbage("setstepmul", 5000) 
 
  -- initialize director 
  local director = cc.Director:getInstance() 
 
  --turn on display FPS 
  director:setDisplayStats(true) 
 
  --set FPS. the default value is 1.0/60 if you don't call this 
  director:setAnimationInterval(1.0 / 60) 
   
  cc.Director:getInstance():getOpenGLView():setDesignResolutionSize(320, 480, 1) 
   
  --create scene  
  local scene = require("GameScene") 
  local gameScene = scene:startGame() 
 
end 

        我們最后調用了GameScene類中的startGame函數(shù),來看看GameScene這個類:

require("Managers.SceneManager") 
require("Managers.LayerManager") 
 
local GameScene = class("GameScene") 
local scene = nil 
 
function GameScene:startGame() 
  --初始化 
  scene = cc.Scene:create() 
  if cc.Director:getInstance():getRunningScene() then 
    cc.Director:getInstance():replaceScene(scene) 
  else 
    cc.Director:getInstance():runWithScene(scene) 
  end 
  SceneManager:initLayer(scene) 
  self:enterGame() 
end 
 
function GameScene:enterGame() 
  LayerManager:getInstance():gotoLayerByType(LAYER_TYPE_MAIN) 
end 
 
return GameScene 

       在startGame函數(shù)中,我們創(chuàng)建了一個空場景,然后調用SceneManager場景管理器來初始化場景。最后調用enterGame函數(shù)正式進入游戲主界面,其中enterGame函數(shù)中又有一個LayerManager層管理器。我們來看看這兩個管理器是如何工作的。先看看SceneManager:

--場景管理器 
SceneManager = {} 
 
--背景層 
bgLayer = nil 
--游戲層 
gameLayer = nil 
--彈窗層 
panelLayer = nil 
 
function SceneManager:initLayer(scene) 
  bgLayer = cc.Layer:create() 
  scene:addChild(bgLayer) 
   
  gameLayer = cc.Layer:create() 
  scene:addChild(gameLayer) 
   
  panelLayer = cc.Layer:create() 
  scene:addChild(panelLayer) 
end 

       很簡單,按順序初始化了三個空Layer。再來看看LayerManager管理器:

--Layer管理器 
LayerManager = {} 
 
LAYER_TYPE_MAIN = "LAYER_TYPE_MAIN" 
 
local curLayer = nil 
 
function LayerManager:new(o) 
  o = o or {} 
  setmetatable(o,self) 
  self.__index = self 
  return o 
end 
 
function LayerManager:getInstance() 
  if self.instance == nil then 
    self.instance = self:new() 
  end 
   
  return self.instance 
end 
 
function LayerManager:gotoLayerByType(type) 
  if curLayer ~= nil then 
    curLayer:destroy() 
  end 
   
  if type == "LAYER_TYPE_MAIN" then 
    local layer = require("Controller.MainLayerController"):create() 
    curLayer = layer 
  end 
end 

        看看gotoLayerByType這個函數(shù),首先切換層的時候,看看當前層是否為空,不為空就刪掉。然后根據(jù)傳遞過來的參數(shù)來判斷要切換到哪個層。這里出現(xiàn)MVC中的Controller部分,看看是什么情況。這里調用了類MainLayerController中的create函數(shù):

function MainLayerC:create() 
  local layer = MainLayerC:new() 
  return layer 
end 
 
function MainLayerC:ctor() 
  self:createUI()--創(chuàng)建界面 
  self:addBtnEventListener()--添加按鈕監(jiān)聽 
end 
 
function MainLayerC:createUI() 
  local layer = require("View.MainLayerView") 
  self.mainLayer = layer:createUI() 
  gameLayer:addChild(self.mainLayer) 
end 

       這里我們又發(fā)現(xiàn)了MVC中的View,在createUI函數(shù)中,我們調用了類MainLayerView的createUI函數(shù),并將其添加到場景的游戲層中。我們來看看MainLayerView這個類。

local eventDispatcher = cc.Director:getInstance():getEventDispatcher() 
 
local MainLayerV = class("MainLayerView",function() 
  return cc.Layer:create() 
end) 
 
function MainLayerV:createUI() 
  local mainLayer = MainLayerV:new() 
  return mainLayer 
end 
 
function MainLayerV:ctor() 
  self:initUI() 
end 
 
function MainLayerV:initUI() 
  local winSize = cc.Director:getInstance():getWinSize() 
  self.bg = cc.Sprite:create(ResManager.main_bg) 
  self.bg:setPosition(winSize.width / 2,winSize.height / 2) 
  self:addChild(self.bg) 
   
  local function menuCallback(tag,menuItem) 
    local event = cc.EventCustom:new(EVENT_CLICK_MENU_MAIN) 
    event._usedata = tag 
    eventDispatcher:dispatchEvent(event) 
  end 
   
  self.btnItem1 = cc.MenuItemImage:create(ResManager.main_btn1,ResManager.main_btn1,ResManager.main_btn1) 
  self.btnItem1:setPosition(winSize.width / 2,winSize.height / 3) 
  self.btnItem1:setTag(1) 
  self.btnItem1:registerScriptTapHandler(menuCallback) 
   
  self.btnItem2 = cc.MenuItemImage:create(ResManager.main_btn2,ResManager.main_btn2) 
  self.btnItem2:setPosition(winSize.width / 2,winSize.height / 2) 
  self.btnItem2:setTag(2) 
  self.btnItem2:registerScriptTapHandler(menuCallback) 
   
  self.btnItem3 = cc.MenuItemImage:create(ResManager.main_btn3,ResManager.main_btn3) 
  self.btnItem3:setPosition(winSize.width / 2,winSize.height / 3 * 2) 
  self.btnItem3:setTag(3) 
  self.btnItem3:registerScriptTapHandler(menuCallback) 
   
  --創(chuàng)建菜單 
  self.menu = cc.Menu:create(self.btnItem1,self.btnItem2,self.btnItem3) 
  self.menu:setPosition(0,0) 
  self:addChild(self.menu) 
end 
 
return MainLayerV 

        可以看到,我們在主界面中添加了一張背景圖和三個按鈕。我們是通過資源管理器ResManager來管理游戲中的素材的,ResManager文件很簡單:

--資源管理器 
ResManager = {} 
 
--主界面 
ResManager.main_bg = "bg_big.png" 
ResManager.main_btn1 = "cell.png" 
ResManager.main_btn2 = "cell2.png" 
ResManager.main_btn3 = "cell3.png" 

       這樣做的好處是,如果圖片改了名字或者換了路徑等,只需要在這里改一次就可以了。

       可以看到我們給三個按鈕注冊了響應函數(shù)menuCallback,在這個函數(shù)中,就是MVC中的V和C之間的“溝通”了。我們定義了一個自定義事件EVENT_CLICK_MENU_MAIN,并給這個事件添加了一個附帶參數(shù)_usedata,這個參數(shù)保存的是三個按鈕的tag。然后將這個事件發(fā)送給他的監(jiān)聽者。這里大家應該明白了,我們在對應的Controller中注冊了EVENT_CLICK_MENU_MAIN的監(jiān)聽,但有這個事件發(fā)過來時,我們就響應。根據(jù)事件攜帶的參數(shù)_usedata,我們就知道了在View中,玩家點擊了哪個按鈕,這樣做的好處是,保證了每個界面只有一個消息,我們只需要根據(jù)這個消息攜帶的附加參數(shù)來判斷具體的事件,從而減少了消息個數(shù),這樣有助于游戲的效率。另外,我們在響應這個消息的時候,也會做一定的優(yōu)化,來看看類MainLayerController的響應函數(shù):

function MainLayerC:addBtnEventListener() 
  --按鈕事件處理 
  local function eventBtnListener(event) 
    local eventNum = event._usedata 
    local switch = { 
      [1] = function() 
        print("Btn one") 
      end, 
      [2] = function() 
        print("Btn two") 
      end, 
      [3] = function() 
        print("Btn three") 
      end 
    } 
    switch[eventNum]() 
  end 
  --注冊事件處理 
  self._eventBtnListener = cc.EventListenerCustom:create(EVENT_CLICK_MENU_MAIN,eventBtnListener) 
  eventDispatcher:addEventListenerWithSceneGraphPriority(self._eventBtnListener,self.mainLayer) 
end 

        可以看到實際情況,我們并不需要對傳遞過來的參數(shù)進行判斷,而是定義了一個函數(shù)數(shù)組,直接根據(jù)下標來調用對應的消息響應。之后繼續(xù)通過各種管理器來對游戲內容進行變化,方式和MainLayerController和MainLayerView差不多。

        到這里,MVC應用的簡單介紹就結束啦,希望大家能夠喜歡本文,能夠對大家學習lua有所幫助。

相關文章

  • Lua中實現(xiàn)StringBuffer功能

    Lua中實現(xiàn)StringBuffer功能

    這篇文章主要介紹了Lua中實現(xiàn)StringBuffer功能,本文給出了實現(xiàn)代碼和調用代碼,需要的朋友可以參考下
    2014-11-11
  • lua日志文件處理代碼

    lua日志文件處理代碼

    本文給大家分享的是使用lua編寫的日志文件的處理代碼,非常的簡單實用,有需要的小伙伴可以參考下。
    2015-09-09
  • Lua中調用C++函數(shù)實例

    Lua中調用C++函數(shù)實例

    這篇文章主要介紹了Lua中調用C++函數(shù)實例,本文是Lua和C++通信系列文章的最后一篇,需要的朋友可以參考下
    2014-09-09
  • Lua中的模塊與module函數(shù)詳解

    Lua中的模塊與module函數(shù)詳解

    這篇文章主要介紹了Lua中的模塊與module函數(shù)詳解,本文講解了編寫一個簡單的模塊、避免修改模塊名的方法、模塊名參數(shù)等內容,需要的朋友可以參考下
    2014-09-09
  • Lua中調用C語言函數(shù)實例

    Lua中調用C語言函數(shù)實例

    這篇文章主要介紹了Lua中調用C語言函數(shù)實例,本文先講解了相關知識,然后給出了調用實例,需要的朋友可以參考下
    2015-04-04
  • lua閉包的理解以及表與函數(shù)的幾種表達方法

    lua閉包的理解以及表與函數(shù)的幾種表達方法

    本文首先通過具體的例子講解了Lua中閉包的概念,然后總結了閉包的應用場合,最后探討了Lua中閉包的實現(xiàn)原理,以及l(fā)ua中表與函數(shù)的3種表達方式的匯總
    2015-08-08
  • Lua中的基本語法、控制語句總結

    Lua中的基本語法、控制語句總結

    這篇文章主要介紹了Lua中的基本語法、控制語句總結,本文總結了賦值、局部變量與塊、控制結構、數(shù)字型for、泛型for等內容,需要的朋友可以參考下
    2014-09-09
  • 簡單談談lua和c的交互

    簡單談談lua和c的交互

    要理解Lua和C++交互,首先要理解Lua堆棧。簡單來說,Lua和C/C++語言通信的主要方法是一個無處不在的虛擬棧。棧的特點是先進后出。
    2016-01-01
  • Lua 中 pairs 和 ipairs 的區(qū)別

    Lua 中 pairs 和 ipairs 的區(qū)別

    這篇文章主要介紹了Lua 中 pairs 和 ipairs 的區(qū)別,本文用官方文檔和代碼實例總結了它的們的區(qū)別,需要的朋友可以參考下
    2014-09-09
  • Luvit像Node.js一樣寫Lua應用

    Luvit像Node.js一樣寫Lua應用

    今天小編就為大家分享一篇關于Luvit像Node.js一樣寫Lua應用,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12

最新評論