亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

lua開發中實現MVC框架的簡單應用

2024-07-21 23:04:27
字體:
來源:轉載
供稿:網友

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

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

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

lua,mvc框架,lua框架

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

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

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

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函數,來看看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函數中,我們創建了一個空場景,然后調用SceneManager場景管理器來初始化場景。最后調用enterGame函數正式進入游戲主界面,其中enterGame函數中又有一個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這個函數,首先切換層的時候,看看當前層是否為空,不為空就刪掉。然后根據傳遞過來的參數來判斷要切換到哪個層。這里出現MVC中的Controller部分,看看是什么情況。這里調用了類MainLayerController中的create函數:

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

       這里我們又發現了MVC中的View,在createUI函數中,我們調用了類MainLayerView的createUI函數,并將其添加到場景的游戲層中。我們來看看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)      --創建菜單   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" 

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

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

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 

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

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

 
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品成人免费电影| 亚洲欧美国产精品久久久久久久| 亚洲欧美中文在线视频| 26uuu另类亚洲欧美日本老年| 久久久久久中文字幕| 欧美一区二区三区免费观看| 国产精品99免视看9| 日韩av在线资源| 一区二区三区www| 欧美另类在线观看| 亚洲精品免费网站| 久久久999精品| 91久久久国产精品| 久久久精品视频在线观看| 成人国产精品一区二区| 欧美精品免费在线| 国产欧美日韩丝袜精品一区| 亚洲一区二区三区xxx视频| 91久久中文字幕| 国产精品第一页在线| 亚洲性线免费观看视频成熟| 久久精品视频一| 久久久久国产精品免费网站| 精品亚洲aⅴ在线观看| 日韩大陆欧美高清视频区| 欧美中文在线观看国产| 91网站在线看| 日韩免费不卡av| 91豆花精品一区| 国产欧美日韩亚洲精品| 97视频在线播放| 欧美大奶子在线| 国产精品96久久久久久| 黄色一区二区在线观看| 欧美网站在线观看| 91精品国产高清自在线看超| 国产精品久久久久aaaa九色| 国产精品99久久99久久久二8| 欧美在线激情网| 亚洲午夜未删减在线观看| 亚洲人成亚洲人成在线观看| 97视频在线播放| 国产精品电影网站| 综合国产在线视频| 亚洲毛片在线看| 欧美片一区二区三区| 日韩电影大片中文字幕| 国产精品免费电影| 精品国产乱码久久久久久婷婷| 国产精品普通话| 日韩精品视频免费| 成人性生交大片免费观看嘿嘿视频| 国产精品igao视频| 亚洲伊人成综合成人网| 国产91在线高潮白浆在线观看| 久久久久久久国产精品视频| 久久精品中文字幕电影| 欧美视频免费在线观看| 亚洲色图校园春色| 青青草原一区二区| 国产精品一二三视频| 欧美日韩成人精品| 日韩美女视频中文字幕| 欧美限制级电影在线观看| 午夜精品一区二区三区视频免费看| 一区二区三区 在线观看视| 久久久久久香蕉网| 日韩欧美在线视频日韩欧美在线视频| 亚洲电影免费观看高清完整版| 91人成网站www| 亚洲欧洲日产国码av系列天堂| 一区二区亚洲欧洲国产日韩| 欧美亚洲另类视频| 亚洲国语精品自产拍在线观看| 亚洲裸体xxxx| 5278欧美一区二区三区| 一本一本久久a久久精品综合小说| 亚洲图片欧洲图片av| 日韩在线免费视频观看| 亚洲国产精品一区二区三区| 亚洲黄色av网站| 97人洗澡人人免费公开视频碰碰碰| 一本大道香蕉久在线播放29| 国产精品视频久久久久| 欧美视频专区一二在线观看| 亚洲深夜福利网站| 国产精品视频精品| 国产精品极品尤物在线观看| 成人午夜激情免费视频| 久久福利视频导航| 欧美精品www在线观看| 国内精品久久久久久久| 欧洲亚洲免费在线| 成人中心免费视频| 亚洲欧美日韩国产中文专区| 亚洲自拍小视频免费观看| 国产精品亚洲精品| 亚洲国产精品电影在线观看| 国产综合色香蕉精品| 国产精品com| 亚洲精品国产精品国自产在线| 亚洲美女精品成人在线视频| 91亚洲va在线va天堂va国| 亚洲国产精品成人一区二区| 欧美孕妇与黑人孕交| 国产精品久久久久久久久久东京| 欧美中文在线免费| 91精品国产九九九久久久亚洲| 91夜夜揉人人捏人人添红杏| 成人美女av在线直播| 国产一区二区三区在线观看视频| 成人国产精品日本在线| 国产精品第一区| 国产精品欧美激情在线播放| 欧美精品在线免费播放| 亚洲欧美国产精品va在线观看| 亚洲一区二区少妇| 不卡av在线网站| 日韩中文字幕视频在线| 欧美久久久精品| 成人网在线免费观看| 精品视频—区二区三区免费| 热久久免费国产视频| 国内外成人免费激情在线视频| 欧美精品一本久久男人的天堂| 亚洲黄色www| 欧美一区二区三区四区在线| 美女视频黄免费的亚洲男人天堂| 国产精品自拍网| 日韩免费在线观看视频| 亚洲片在线资源| 国产精品男人的天堂| 欧美在线一区二区视频| 亚洲国产小视频| 精品小视频在线| 国产精品日韩久久久久| 精品露脸国产偷人在视频| 久久久久久久久久久成人| 欧美激情按摩在线| 国产精品九九久久久久久久| 2019中文字幕在线观看| 国产成人精品久久| 成人激情视频在线观看| 精品视频—区二区三区免费| 91在线免费网站| 欧美日韩国产成人| 亚洲成人精品在线| 亚洲精品一区二区三区婷婷月| 91免费电影网站| 欧美裸体xxxx极品少妇软件| 中国china体内裑精亚洲片| 久久久久一本一区二区青青蜜月| 国产精品高潮呻吟视频| 91久久久久久| 亚洲日韩中文字幕| 国产+成+人+亚洲欧洲| 国产成人亚洲综合91| 亚洲国产精品视频在线观看| 91国内在线视频| 色偷偷91综合久久噜噜| 日韩性生活视频| 国产一区二区三区三区在线观看| 色偷偷88888欧美精品久久久| 欧美大尺度在线观看|