国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Lua - lua開發中實現MVC框架的簡單應用

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

2020-04-21 11:09hebedich Lua

最近的游戲項目中使用了lua腳本來開發,項目中用到了MVC框架,最近有朋友問我怎么弄,在這里簡單分享一下思路和一些開發中的技巧。有需要的小伙伴可以參考下。

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

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

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

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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這個類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
--場景管理器
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管理器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
--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函數:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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這個類。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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文件很簡單:

?
1
2
3
4
5
6
7
8
--資源管理器
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的響應函數:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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有所幫助。

延伸 · 閱讀

精彩推薦
  • LuaLua中的元方法__newindex詳解

    Lua中的元方法__newindex詳解

    這篇文章主要介紹了Lua中的元方法__newindex詳解,本文講解了查詢與更新、監控賦值、通過table給另一個table賦值等內容,需要的朋友可以參考下 ...

    笨木頭8872020-04-09
  • LuaLua中table庫函數方法介紹

    Lua中table庫函數方法介紹

    這篇文章主要介紹了Lua中table庫函數方法介紹,本文講解了concat、insert、maxn、remove、sort、foreachi等方法,需要的朋友可以參考下 ...

    腳本之家2502020-04-17
  • Lua深入探究Lua中的解析表達式

    深入探究Lua中的解析表達式

    這篇文章主要介紹了深入探究Lua中的解析表達式,對于其語法部分的說明和示例都超詳細,極力推薦此文!需要的朋友可以參考下 ...

    腳本之家3542020-05-05
  • LuaLua中計算、執行字符串中Lua代碼的方法

    Lua中計算、執行字符串中Lua代碼的方法

    這篇文章主要介紹了Lua中計算、執行字符串中Lua代碼的方法,類似JavaScript中eval函數的功能,在Lua中也可以實現,需要的朋友可以參考下 ...

    腳本之家6322020-04-30
  • LuaLua簡介、編譯安裝教程及變量等語法介紹

    Lua簡介、編譯安裝教程及變量等語法介紹

    這篇文章主要介紹了Lua簡介、編譯安裝教程及變量等語法介紹,本文同時講解了lua注釋語法、Lua命令行方式等內容,需要的朋友可以參考下 ...

    junjie3632020-04-14
  • LuaLua教程(二):基礎知識、類型與值介紹

    Lua教程(二):基礎知識、類型與值介紹

    這篇文章主要介紹了Lua教程(二):基礎知識、類型與值介紹,本文講解了Hello World程序、代碼規范、全局變量、類型與值等內容,需要的朋友可以參考下 ...

    腳本之家5922020-04-28
  • LuaLua實現__add方法重載示例

    Lua實現__add方法重載示例

    這篇文章主要介紹了Lua實現__add方法重載示例,本文直接給出實現代碼,需要的朋友可以參考下 ...

    腳本之家7452020-04-24
  • LuaLua和C語言的交互詳解

    Lua和C語言的交互詳解

    這篇文章主要介紹了Lua和C語言的交互詳解,Lua和C語言通過棧完成交互,本文結合代碼實例詳細講解了交互的方法,需要的朋友可以參考下 ...

    果凍想3702020-04-14
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 免费成人高清在线视频 | 青青草久 | 可以看的毛片网站 | 亚洲国产高清在线 | av官网| 91精品久久久久久久久久 | 一级特黄a免费观看视频 | 久久草在线视频 | 欧美日韩亚洲一区 | 日本中文字幕一区二区 | 久久精品xx老女人老配少 | 中文字幕久久精品 | 国产精品1区 | 嫩草网站在线观看 | 午夜免费视频福利 | 国产在线第一页 | 91精品国产91久久久久久黑人 | a∨色狠狠一区二区三区 | 中文字幕在线一区 | 国产欧美精品一区二区三区 | 日韩在线视频一区 | 中文字幕亚洲综合久久久软件 | 精品国产免费久久久久久尖叫 | 欧美在线不卡 | 久久综合伊人 | 91亚洲精品乱码久久久久久蜜桃 | 国产一区二区三区久久久久久久久 | 欧美日韩视频在线 | 精品久久一区 | 久久精品免费一区二区三区 | 色视频www在线播放国产人成 | 成人欧美一区二区三区视频xxx | 天天干天天草 | 亚洲网在线| 国产精品久久久久aaaa九色 | 欧美一级全黄 | 亚洲人一区二区 | 国产精品美女 | 成人在线观看免费视频 | 亚洲国产精品一区二区久久 | 日本一区二区视频 |