cocos2dx里加载cocosudio导出的ui配置文件,在这之上封装了一下,封装核心类包括

UIManager,UILayer,UIOwner

UIManager是所有ui总的管理类,代码如下:

UIManager = {
battle = 1,
city = 2,
login = 4,
select = 8,
create = 16,
-- room = 32,
movie = 64,
dance = 128,
arena = 256,
house = 512,
format = 1024,
dress = 2048,
astro = 4096,
cook = 8192,
god = 16384,
video = 32768,
boss = 32768*2,
fish = 32768*4,
farm = 32768*8,
spa = 32768*16,
pokersel= 32768*32,
poker = 32768*64,
back = 32768*128,
none = 0,
all = 0xffffffff,

bottom = 1,
game = 2,
pop = 3,
high = 4,
top = 5,
}
_class( "UIManager", Object );

local instance
function UIManager.getInstance()
if not instance then
instance=UIManager:new();
end
return instance;
end

function UIManager.new( self )
local instance = Object.new( self );
instance._layer=cc.Layer:create();
instance:addLayer(UILayer:new(), UILayer:new(), UILayer:new(),UILayer:new(),UILayer:new());
return instance
end

function UIManager.getLayer( self, layer )
return array.indexOf( self.layers, layer );
end

function UIManager.addLayer( self, ... )
for i = 1, select("#", ...) do
local layer = select(i, ...);
layer.owner = self;
table.insert(self.layers, layer)
self._layer:add(layer, i)
end
end

function UIManager.addSwf( self, swfowner, lay, depth )
self.layers[lay]:add( swfowner, depth );
end

function UIManager.removeSwf( self, swfowner )
if not swfowner.container then return; end;
swfowner.container:remove( swfowner );
end

function UIManager.enterDomain( self, domain )
for i = 1, #self.layers do
self.layers[i]:enterDomain(domain);
end
self.domain = domain;
end

function UIManager.onIdle(self, e)
for i = 1, #self.layers do
self.layers[i]:onIdle(e)
end
end

function UIManager.disMe(self)
end

UIOwner是每个ui的实例,UIManager分层管理UIOwner,UILayer的代码如下:

UILayer = {}
_class( "UILayer", EventDispatcher )

function UILayer.new( self )
local instance = Object.new( self );
instance.uis = {}; -- collections of uiowner
instance.depths = {};
instance._layer=cc.Layer:create();
return instance;
end

function UILayer.add( self, ui, depth )
depth = depth or self:getNextDepth();
local len=#self.uis;
for i = 1, len do
if self.uis[i] == ui then
self:topui(self.uis[j]):top();
for j = i+1, table.maxn( self.uis ) do
self:topui(self.uis[j]):top();
end
return;
end
end
local i = 1;
while i <= len do
if self.depths[i] > depth then
break;
end
i = i + 1;
end
table.insert( self.uis, i, ui );
table.insert( self.depths, i, depth );
self:topui(ui);
i = i + 1;
while i <= len+1 do
self:topui(self.uis[i]);--排序
i = i + 1;
end
ui.container = self;
end

function UILayer.pop( self, ui )
for i = 1, table.maxn( self.uis ) do
if self.uis[i] == ui then
table.remove( self.uis, i );
table.remove( self.depths, i );
self._layer:removeChild(ui._ui);
return ui;
end
end
end

function UILayer.topui(self, ui)
ui:setlocalZOrder(self:getNextDepth())
end

function UILayer.remove( self, ui )
for i = 1, table.maxn( self.uis ) do
if self.uis[i] == ui then
self.uis[i]:disMe();
table.remove( self.uis, i );
table.remove( self.depths, i );
self._layer:removeChild(ui._ui);
return;
end
end
end

function UILayer.setDepth( self, ui, depth )
local i = array.indexOf( self.uis, ui );
if ( not self.depths[i-1] or self.depths[i-1] < depth ) and ( not self.depths[i+1] or self.depths[i+1] > depth ) then
self.depths[i] = depth;
return;
elseif depth > self.depths[i] then
self:topui(ui);
table.remove( self.depths, i );
table.remove( self.uis, i );
local binsert = false;
for ii = i + 1, #self.uis do
if self.depths[ii] > depth then
if not binsert then
table.insert( self.uis, ii , ui );
table.insert( self.depths, ii, depth );
binsert = true;
end
self:topui(self.uis[ii]);
end
end
if not binsert then
table.insert( self.uis, ui );
table.insert( self.depths, depth );
end
elseif depth < self.depths[i] then
table.remove( self.depths, i );
table.remove( self.uis, i );
local binsert = false;
for ii = 1, #self.uis do
if self.depths[ii] > depth then
if not binsert then
table.insert( self.uis, ii , ui );
table.insert( self.depths, ii, depth );
binsert = true;
end
self:topui(self.uis[ii]);--排序
end
end
if not binsert then
table.insert( self.uis, ui );
table.insert( self.depths, depth );
end
end
end

function UILayer.getLayer( self )
return self.owner:getLayer( self );
end

function UILayer.getDepth( self, ui )
local i = array.indexOf( self.uis, ui );
return self.depths[i];
end

function UILayer.top( self, ui ) -- uiowner
local i = array.indexOf( self.uis, ui );
if i == table.maxn( self.uis ) then return; end
table.remove( self.uis, i );
table.remove( self.depths, i );
table.insert( self.uis, ui );
local depth=self:getNextDepth();
table.insert( self.depths, depth );
self._layer:_setLocalZOrder(depth);
end

function UILayer.getNextDepth( self )
if table.maxn( self.depths ) == 0 then return 1 end;
return toint( self.depths[table.maxn( self.depths )] + 1 ) ;
end

function UILayer.onIdle(self, e)
for i = 1, #self.uis do
if self.uis[i]:isShow() then
self.uis[i]:onIdle(e);
end
end
end

function UILayer.clear( self )
for _, ui in next, self.uis do
ui:disMe();
end
self.uis = {};
self.depths = {};
return self;
end

UIOwner是每个ui的封装的,其中_ui属性对应加载进来node对象,代码如下:

local function loadui(res)
return ccs.GUIReader:shareReader():widgetFromJsonFile("res/SampleChangeEquip_1.json");
end

UIOwner={}
_class("UIOwner", Object)
function UIOwner.new(self, url, layer, depth, domain)
local instance=Object.new(self)
self._ui=loadui(url);
_uimanager:addSwf( instance, lay, depth );
instance.domain = domain or UIManager.none;
instance._name = url;
SwfOwner.show( instance, true );
return self
end

function UIOwner.isShow(self)
return self._show;
end

function UIOwner.show(self, b)
b = toboolean(b);
local os = self:isShow();
if os ~= b then
self._show = b;
end
if self:isShow() then
self:onResize();
elseif os then
fadeclear(self);
end
return self;
end

function UIOnwer.onIdle(self, e)
end

function UIOwner.disMe(self)

end

下面举个登录的例子:

LoginUI={}
_class("LoginUI", UIOwner)
function LoginUI.new(self)
local instance=Object.new(self, "login.luf", 1, UIManager.login)
instance:setClick();
return instance;
end

function LoginUI.show(self, b)
local os=self:isShow();
SwfOwner.show(self, b);
if self:isShow() then
if not os then
self:updateInfo()
end
end
return self;
end

function LoginUI.updateInfo()
end

还有个全局的show方法如下:

function showLoginUI ( b )
local name = "loginui";
if uiargs["showLoginUI"] then
uiargs["showLoginUI"]= {b};
local oldDomain = _swfs.manager.domain;
return;
end
if not _swfs[name] then
if b == false then return; end
uiargs["showLoginUI"] = {b};
callinWait(true);
local oldDomain = UIManager:getInstance().domain;
local process = UIProcess:getInstance():show(true);
local loader = _Loader.new();
loader:onFinish(function()
_swfs[name] = LoginUI:new():show(false);
local args = uiargs["showLoginUI"];
uiargs["showLoginUI"]=nil;
if _swfs[name]:checkDomain(oldDomain) then
showLoginUI(unpack(args));
end

process:close();uiloaders[loader]=nil;
callinWait(false);
end);
loader:onProgress(function(per) process:setProgress(toint(per*100)); end)
loader:load( "loginui.luf" );uiloaders[loader]=loader
print(loader.progress);
return;
end
local oldShow = _swfs[name]:isShow();
b = ( b == nil and not _swfs[name]:isShow() ) or b;
if b and b ~= oldShow then
end
_swfs[name]:show( b );
end

整个封装的两点好处在于:

1其他的ui实现以及show方法和这个非常相似,实际中的代码是是用工具生成,可以极大加快开发速度,估计不是很复杂的界面,一天能完成4-6个左右界面

2不直接操作引用,对Ui的操作都是通过方法实现的,可以杜绝内存泄露,而且因为所有的实例生成都从object.new走 ,可以实现1个通用的monitor,监视对象实例个数,便于查找lua对象泄露

整个封装是从原来的页游项目拷贝修改过的,原来的底层实现是通过scaleform加载swf,即使底层实现不一样,但是上层封装可以做到一致,这个封装与底层实现耦合度低(曾经用flash as实现过基本一样的封装)

整个搬过来的时候,没有调试过,等之后的场景封装完事之后,都调通了,会再上传1份完整点的包

cocos2dx的ui封装的更多相关文章

  1. 特别好用的swagger ui 封装

    Swagger简单介绍 Swagger是一个Restful风格接口的文档在线自动生成和测试的框架 官网:http://swagger.io 官方描述:The World’s Most Popular ...

  2. Cocos2d-x之UI控件简介

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 在Cocos2d-x中提供了一种UI控件,UI控件是指用户交互界面的操作部件.UI控件可以是Button(按钮),CheckBox(选择框 ...

  3. COCOS2D-X中UI动画导致闪退与UI动画浅析

    前两天和同事一起查一个游戏的闪退问题,log日志显示最后挂在CCNode* ActionNode::getActionNode()函数中的首行CCNode* cNode = dynamic_cast& ...

  4. JQuery UI 封装了一些常用模板

    1.css 他已经封装了一些css样式,如果不喜欢,可以直接修改. 2.js 他已经封装了对应的js.

  5. cocos2dx - Sqlite简单封装使用

    前言: 一般游戏需要在手机上记录一些简单的信息,用来保存游戏的进度,玩家的分数等.SQLite作为轻量级.跨平台的关系型数据库,相当适合用于游戏数据的存储. 由于没有加密,有安全性问题,数据上还需要自 ...

  6. cocos2D-X 常用功能封装

    Packaging_Kernel.h #pragma once #include <string> #include <map> #include <vector> ...

  7. cocos2d-x 常用UI

    CCSprite* sprite = CCSprite::create("CloseNormal.png"); sprite->setPosition(ccp(50, 50) ...

  8. 关于Cocos2d-x中UI按钮的定义

    1.要有两张不同状态的图片 2.定义一个MenuItemSprite的实例,把这两张图的Sprite实例放进MenuItemSprite的实例 3.把MenuItemSprite的实例放进Menu实例 ...

  9. `cocos2dx 非完整` UI解析模块

    昨天在cocos2dx的一个群里,遇到一位匿名为x的朋友询问的问题,是关于ui的.他使用c++写了不少的ui封装节点,用来实现游戏中的各种不同效果.然后现在想改用lua,于是尝试使用最小代价去复用自己 ...

随机推荐

  1. 20160208.CCPP体系具体解释(0018天)

    程序片段(01):main.c 内容概要:PointWithOutInit #include <stdio.h> #include <stdlib.h> //01.野指针具体解 ...

  2. SSO单点登录系列6:cas单点登录防止登出退出后刷新后退ticket失效报500错

    这个问题之前就发现过,最近有几个哥们一直在问我这个怎么搞,我手上在做另一个项目,cas就暂时搁浅了几周.现在我们来一起改一下你的应用(client2/3)的web.xml来解决这个2b问题,首先看下错 ...

  3. [Unit Testing] Mock a Node module's dependencies using Proxyquire

    Sometimes when writing a unit test, you know that the module you're testing imports a module that yo ...

  4. Python&lt;1&gt;List

    list里的元素以逗号隔开,以[]包围,当中元素的类型随意 官方一点的说:list列表是一个随意类型的对象的位置相关的有序集合. 它没有固定的大小(1).通过对偏移量 (2)进行赋值以及其它各种列表的 ...

  5. Android官方SwipeRefreshLayout

    App基本都有下拉刷新的功能,以前基本都使用PullToRefresh或者自己写一个下拉刷新,Google提供了一个官方的下拉刷新控件SwipeRefreshLayout,简单高效,满足一般需求足够了 ...

  6. Centos——升级Python2.7及安装pip

    CentOS升级Python2.7及安装pip 1) 升级Python2.7 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ...

  7. [转]Tomcat处理一个HTTP请求的过程

    1.Tomcat Server的组成部分 1.1 - Server A Server element represents the entire Catalina servlet container. ...

  8. Mybatis 批量插入数据

    --mybatis 批量插入数据 --1.Oracle(需要测试下是否支持MySQL) < insert id ="insertBatch" parameterType=&q ...

  9. PHP使用微软认知服务Face API

    下面主要介绍基于PHP语言,基于guzzle类库,调用微软最新推出的认知服务:人脸识别. 实验环境: IDE:Eclipse for PHP Developers Version: Neon.1 Re ...

  10. 高度平衡树 -- AVL 树

    Scheme 的表达, 优雅. #lang scheme ( define nil '() ) ( define ( root tree )( car tree ) ) ( define ( left ...