cocos2dx之lua项目开发中MVC框架的简单应用

简介:
****************************************************************************

时间:2015-03-31

作者:Sharing_Li

转载注明出处:http://blog.csdn.net/sharing_li/article/details/44658317

****************************************************************************

 

       近期的游戏项目中使用了lua脚本来开发,项目中用到了MVC框架,近期有朋友问我怎么弄。在这里简单分享一下思路和一些开发中的技巧。 

       先简单说说MVC,即Model View Controller。Model(模型),一般负责数据的处理。View(视图)。一般负责界面的显示。Controller(控制器),一般负责前端的逻辑处理。拿一款手机游戏来说,界面UI的显示、布局等就是View负责;点击了button,手势的滑动等操作由Controller来处理;游戏中须要的数据资源就交给Model。 

       接下来,看看在游戏开发中怎么用,这里用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

       非常easy,按顺序初始化了三个空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()--加入button监听
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


        能够看到,我们在主界面中加入了一张背景图和三个button。我们是通过资源管理器ResManager来管理游戏中的素材的。ResManager文件非常easy:

--资源管理器
ResManager = {}

--主界面
ResManager.main_bg = "bg_big.png"
ResManager.main_btn1 = "cell.png"
ResManager.main_btn2 = "cell2.png"
ResManager.main_btn3 = "cell3.png"

       这样做的优点是,假设图片改了名字或者换了路径等。仅仅须要在这里改一次就能够了。

       能够看到我们给三个button注冊了响应函数menuCallback,在这个函数中。就是MVC中的V和C之间的“沟通”了。

我们定义了一个自己定义事件EVENT_CLICK_MENU_MAIN,并给这个事件加入了一个附带參数_usedata,这个參数保存的是三个button的tag。然后将这个事件发送给他的监听者。这里大家应该明确了,我们在相应的Controller中注冊了EVENT_CLICK_MENU_MAIN的监听,但有这个事件发过来时。我们就响应。依据事件携带的參数_usedata,我们就知道了在View中。玩家点击了哪个button。这样做的优点是,保证了每一个界面仅仅有一个消息。我们仅仅须要依据这个消息携带的附加參数来推断详细的事件,从而降低了消息个数,这样有助于游戏的效率。另外,我们在响应这个消息的时候,也会做一定的优化,来看看类MainLayerController的响应函数:

function MainLayerC:addBtnEventListener()
	--button事件处理
	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应用的简介就结束啦。免费下载代码












本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5125274.html,如需转载请自行联系原作者


相关文章
|
5天前
|
设计模式 开发框架 前端开发
MVC 模式在 C# 中的应用
MVC(Model-View-Controller)模式是广泛应用于Web应用程序开发的设计模式,将应用分为模型(存储数据及逻辑)、视图(展示数据给用户)和控制器(处理用户输入并控制模型与视图交互)三部分,有助于管理复杂应用并提高代码可读性和维护性。在C#中,ASP.NET MVC框架常用于构建基于MVC模式的Web应用,通过定义模型、控制器和视图,实现结构清晰且易维护的应用程序。
13 2
|
5月前
|
前端开发 Java 测试技术
Java一分钟之Spring MVC:构建Web应用
【5月更文挑战第15天】Spring MVC是Spring框架的Web应用模块,基于MVC模式实现业务、数据和UI解耦。常见问题包括:配置DispatcherServlet、Controller映射错误、视图解析未设置、Model数据传递遗漏、异常处理未配置、依赖注入缺失和忽视单元测试。解决这些问题可提升代码质量和应用性能。注意配置`web.xml`、`@RequestMapping`、`ViewResolver`、`Model`、`@ExceptionHandler`、`@Autowired`,并编写测试用例。
328 3
|
2月前
|
存储 前端开发 数据库
神秘编程世界惊现强大架构!Web2py 的 MVC 究竟隐藏着怎样的神奇魔力?带你探索实际应用之谜!
【8月更文挑战第31天】在现代 Web 开发中,MVC(Model-View-Controller)架构被广泛应用,将应用程序分为模型、视图和控制器三个部分,有助于提高代码的可维护性、可扩展性和可测试性。Web2py 是一个采用 MVC 架构的 Python Web 框架,其中模型处理数据和业务逻辑,视图负责呈现数据给用户,控制器则协调模型和视图之间的交互。
28 0
|
2月前
|
设计模式 存储 前端开发
MVC 框架的主要问题是什么?
【8月更文挑战第30天】
30 0
|
4月前
|
数据挖掘 Linux 数据处理
探索Linux下的Lua命令:轻量级脚本语言在数据处理和分析中的应用
**探索Linux上的Lua:轻量级脚本语言用于数据处理。Lua通过命令行解释器执行,适用于游戏开发、数据分析及自动化。特点包括小巧、高效、可扩展和动态类型。使用`lua`或`luajit`,配合-e、-l、-i参数执行脚本或互动模式。示例:执行`hello.lua`脚本打印"Hello, Lua!"。最佳实践涉及版本兼容、性能优化、使用C API、测试和文档编写。**
|
4月前
|
JSON 前端开发 Java
Spring第四课,MVC终章,应用分层的好处,总结
Spring第四课,MVC终章,应用分层的好处,总结
|
4月前
|
安全 前端开发 测试技术
安全开发-PHP应用&模版引用&Smarty渲染&MVC模型&数据联动&RCE安全&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞
安全开发-PHP应用&模版引用&Smarty渲染&MVC模型&数据联动&RCE安全&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞
|
4月前
|
前端开发 测试技术 API
探索安卓应用的架构演进:从MVC到MVVM
本篇文章将深入探讨安卓应用开发中的架构演进,特别关注从传统的MVC(Model-View-Controller)到现代流行的MVVM(Model-View-ViewModel)架构的转变。通过对比两种架构的设计理念、实现方式和实际应用案例,解析MVVM在提高代码可维护性和可测试性方面的优势。
52 0
|
5月前
|
前端开发 JavaScript 开发者
深入理解MVC和MVVM:构建现代Web应用的利器
深入理解MVC和MVVM:构建现代Web应用的利器
|
5月前
|
前端开发 Java Spring
Java Web ——MVC基础框架讲解及代码演示(下)
Java Web ——MVC基础框架讲解及代码演示
50 1
下一篇
无影云桌面