lua开发中实现MVC框架的简单应用-VC编程
小标 2018-05-16 来源 : 阅读 1186 评论 0

摘要:在VC编程中,先简单说说MVC,即Model View Controller。Model(模型),一般负责数据的处理;View(视图),一般负责界面的显示;Controller(控制器),一般负责前端的逻辑处理。拿一款手机游戏来说,界面UI的显示、布局等就是View负责;点击了按钮,手势的滑动等操作由Controller来处理;游戏中需要的数据资源就交给Model。希望对大家学习VC编程有所帮助。

    在VC编程中,先简单说说MVC,即Model View Controller。Model(模型),一般负责数据的处理;View(视图),一般负责界面的显示;Controller(控制器),一般负责前端的逻辑处理。拿一款手机游戏来说,界面UI的显示、布局等就是View负责;点击了按钮,手势的滑动等操作由Controller来处理;游戏中需要的数据资源就交给Model。希望对大家学习VC编程有所帮助。

       接下来,看看在游戏开发中怎么用,这里用Lua(环境使用cocos code ide)给大家说说。

       先来看看项目的目录结构:

 

        其中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 {}

  set<d>meta</d>table(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:register<d>Script</d>TapHandler(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:register<d>Script</d>TapHandler(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:register<d>Script</d>TapHandler(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有所帮助。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言VC/MFC频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程