Introduction to MVCMVC, the model View Controller.
model (models), generally responsible for the processing of data , view
(view), generally responsible for the display of the interface ; Controller,
usually responsible for the front-end logic processing . Take a mobile phone game, the interface UI display, layout and so on is the view responsible for, click on the button, gestures, such as the swipe of the controller to deal with, the game needs the data resources to give model.
Among them cocos, Controller, Model, view this needless to say, the
event inside the global message type saved ,
managers is used to manage the game in the east, such as management resources, management of various scene switching, layer switching and so on.
Utilities provides some tool classes, such as string processing . You can also customize the directory according to your needs, such as defining a Netcenter folder that is designed to handle the network. Data manipulation and tool classes are not used in this example, so the two folders are empty. Process Instancewe use the game's running process as clues to unfold the instructions. To run the project, go to the Main.lua file and take a look at the main function:
Local function Main () collectgarbage (collect) --Avoid memory leak CollectGarbage (setpause, +) CollectGarbage (Setstepmul) --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 (480, 1) --create scene local scene = Require (gamescene) Local gamescene = Scene:startgame () end
We finally called the Startgame function in the Gamescene class to see the Gamescene class:
Require (Managers.scenemanager) require (managers.layermanager) Local gamescene = Class (gamescene) Local scene = Nil function Gamescene:startgame () --Initialize 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
In the Startgame function, we created an empty scene and then called the Scenemanager scene manager to initialize the scene. Finally call the Entergame function formally into the game main interface, where the Entergame function has a Layermanager layer manager. Let's take a look at how these two managers work. First Look at Scenemanager:
--Scene Manager Scenemanager = {}--background layer Bglayer = nil--game Layer Gamelayer = nil--popup Layer Panellayer = Nil function Scenemanager:initlayer (scen e) bglayer = cc. Layer:create () scene:addchild (bglayer) gamelayer = cc. Layer:create () scene:addchild (gamelayer) panellayer = cc. Layer:create () scene:addchild (panellayer) End
It is simple to initialize three empty layers sequentially. Look again at the Layermanager Manager:
--layer Manager Layermanager = {} Layer_type_main = Layer_type_main local Curlayer = Nil function layermanager:new (o) o = O or {} setmetatable (o,self) self.__index = self return oend function layermanager:getinstance () if Self.instance = = Nil then self.instance = self:new () end return self.instanceend 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 endend
See Gotolayerbytype This function, first switch layer, to see whether the current layer is empty, not empty is deleted. It then determines which layer to switch to, based on the parameters passed.
Here's the controller part of MVC to see what happens. This invokes the CREATE function in the class Mainlayercontroller .:
function mainlayerc:create () Local layer = mainlayerc:new () return layerend function mainlayerc:ctor () Self:createui ()--Create Interface Self:addbtneventlistener ()--add button to listen to End Function Mainlayerc:createui () Local layer = Require (View.mainlayerview) Self.mainlayer = Layer:createui () gamelayer:addchild (self.mainlayer) End
Here we find the view in MVC, in the Createui function, we call the Createui function of class Mainlayerview and add it to the game layer of the scene .。 Let's take a look at the Mainlayerview class.
Local eventdispatcher = cc. Director:getinstance (): Geteventdispatcher () Local mainlayerv = Class (Mainlayerview,function () return CC. Layer:create () end) function Mainlayerv:createui () Local mainlayer = Mainlayerv:new () return mainlayerend function Ma Inlayerv: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.btnite M3 = 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)--Create Menu Self.menu = cc. Menu:create (SELF.BTNITEM1,SELF.BTNITEM2,SELF.BTNITEM3) self.menu:setPosition (0,0) self:addchild (self.menu) End Return Mainlayerv
As you can see, we've added a background map and three buttons to the main interface. We manage the footage in the game through the resource Manager Resmanager, and the Resmanager file is simple:
--Resource Manager Resmanager = {}--main interface RESMANAGER.MAIN_BG = BG_BIG.PNGRESMANAGER.MAIN_BTN1 = CELL.PNGRESMANAGER.MAIN_BTN2 = Cell2.pngResManager.main_btn3 = Cell3.png
The advantage of this is that if you change the name of the picture or change the path, you just need to change it here.
You can see that we've registered the response function Menucallback for three buttons, in which the
"communication" between V and C in MVC is in this function . We define a custom event Event_click_menu_main and add a parameter _usedata to the event, which holds the tag for three buttons. The event is then sent to his listener. It should be understood here that we registered the Event_click_menu_main monitor in the corresponding controller, but when this event came, we responded. According to the parameters carried by the event _usedata, we know in the view, the player clicked which button, the advantage is that the
guarantee that each interface only one message , we only need to according to the message carries the additional parameters to determine the specific event, This reduces the number of messages, which helps the game to be efficient . In addition, when we respond to this message, we will also do some optimizations to see the response function of class Mainlayercontroller:
function Mainlayerc:addbtneventlistener () --button event handling local function Eventbtnlistener (event) Local Eventnum = event._usedata Local switch = { [1] = function () print (Btn one) end, [2] = function () print (BTN) end, [3] = function () print (Btn three) end } Switch[eventnum] () End --register event handling Self._eventbtnlistener = cc. Eventlistenercustom:create (Event_click_menu_main,eventbtnlistener) Eventdispatcher: Addeventlistenerwithscenegraphpriority (Self._eventbtnlistener,self.mainlayer) End
As you can see, we do not need to judge the arguments passed, but we define an array of functions that invoke the corresponding message response directly from the subscript. Then continue to change the game content through various managers in the same way as Mainlayercontroller and Mainlayerview. Cocos2dx-lua Framework Process
Many learners don't even know why Enterscene ("Mainscene") can be a string.
After you create a new Cocos2dx-lua project, you first see the Main.lua boot to Myapp.lua.
Require ("app. MyApp "). New (): Run ()
See Myapp.lua file:
1. require ("app. MyApp ")
The code for the Myapp.lua executed here is:
Local MyApp = Class ("MyApp", Cc.mvc.AppBase) --Inherit Cc.mvc.AppBasereturn MyApp
at this point, you get the MyApp class (LUA on the implementation of the class online a lot)
2. require ("app. MyApp "). New ()
After Myapp.new () executes, the code executed is:
function Myapp:ctor () MyApp.super.ctor (self) End
Why does the Myapp:ctor () run after new ()? Take a look at the function class (classname, Super) method under Function.lua:
function Cls.new (...) Local instance = cls.__create (...) --copy fields from class to native object for k,v in pairs (CLS) do instance[k] = v End Instance.class = CLS I Nstance:ctor (...) Return Instanceend
as you can see, in the class implementation method, a new () method is declared for each class that is created, and the method calls the ctor () constructor (ctor is just a name, so not some people think that the new, of course, will call the constructor method, Lua has no class, Just we imitated the class)
3. require ("app. MyApp "). New (): Run ()
This is called
function Myapp:run () ccfileutils:sharedfileutils (): Addsearchpath ("res/") self:enterscene ("Mainscene") End
so I went into the Mainscene.lua.
For the Myapp.lua file, if I modify it to look like this, do you understand the above:
--Declaring the class MyApp = Class ("MyApp", Cc.mvc.AppBase) ---Class construction method--function Myapp:ctor () MyApp.super.ctor (self) End--- The static Create () method corresponding to the CPP version--function myapp:create () Local MyApp = Myapp.new () myapp:init () End---your own method-@ Param self--local function launchmainscene (self) ccfileutils:sharedfileutils (): Addsearchpath ("res/") self : Enterscene ("Mainscene") End---init method--function myapp:init () --Add code here Launchmainscene (self) End
The corresponding Main.lua will be the original require ("app. MyApp "). New (): Run ()
Modified to:
Require ("app. MyApp ") myapp:create ()
It's easier for you to understand, haha.
4. Mainscene.lua
Enterscene ("Mainscene") why can I switch scenes?
Let's look at the appbase of the parent of MyApp:
function Appbase:enterscene (scenename, args, Transitiontype, time, more) local scenepackagename = self. packageroot .. ". Scenes.". Scenename Local Sceneclass = require (scenepackagename) local scene = Sceneclass.new (Unpack (totable (args))) display.replacescene (Scene, Transitiontype, time, more) end
so you can understand why even require files can not be called mainscene, of course, you have to note that it require time the file path, scene default write App/scenes folder. Well, the rest should follow the above-mentioned ideas and basically know why.
Lua's MVC framework Sailor
Sailor is an MVC programming framework for the Lua language . Support cross-platform, compatible with Mod_lua or Mod_plua, Nginx Ngx_lua, or any CGI-enabled Web server, such as Civetweb or Mongoose, provided there is a need for Cgilua. The directory structure for developing apps using Sailor is as follows:
- /conf-Storing configuration files
- /controllers-Controller
- /layouts-Layout file
- /models-Model
- /pub-Static files
- /runtime-Temporary files generated at run time
- /views-. LP View File
Framework MVC in Cocos2dx]cocos2dx-lua