基于cocos2d -x的一个强大的 界面对象的基类
1 ---@type uinode ui 对象的抽象 2 --@usage 3 -- 界面打开的执行流程 4 -- 带*的是可选重写的函数,不带*的为必须实现的 5 -- [定义一个对象] 6 -- test = {} 7 -- -------------------------------------------- 8 -- ---配置函数 9 -- [返回CCBI的名字] 10 -- function test:getBindUINodeStr() end 11 -- [*显示模式,不实现是直接打开。不会居中] 12 -- function test:getShowModel() end 13 -- -------------------------------------------- 14 -- ---流程函数 15 -- [*打开界面前要执行网络操作] 16 -- function test:getCmdStr() end 17 -- [*打开界面前要执行网络操作需要的数据] 18 -- function test:getCmdData() end 19 -- 网络命令成功后会进行的操作 20 -- function test:onRemoteAck(networkArgs) end 21 -- [*初始化界面上的相关信息] 22 -- function test:on_initUI(node,openArgs,networkArgs) end 23 -- [*关闭界面前要进行网络通信] 24 -- function test:before_close(ackfun) end 25 -- ----------------------------------------------------------------- 26 -- PS:当有*函数的出现,只要*函数执行成功,才会调用之后的函数 27 -- 28 -- usage: local obj = test.getInstance() 29 -- obj:open(args) --args 为要传送到on_initUI中的args数据 30 uinode ={} 31 32 require("base") 33 require("userGuidelines") 34 35 ---=============================================================== 36 ---IUiNode interface 37 IUiNode = {} 38 ---IUiNode interface 39 createInterface(IUiNode,"IUiNode",function(self,openArgs) end) 40 ---=============================================================== 41 42 ---@field 是否为中心显示 43 uinode.isShowInCenterFlg = false 44 ---@field 当前绑定的节点 45 --@return #cc.Node cc.node节点 46 uinode.node = nil 47 uinode ,supper= inheritance(uinode,object) 48 49 ------------------------------------------------------------------------ 50 --显示模式定义 51 uinode.showModel = { 52 NOTADDTO_CONTENT = -1, 53 NONE = 0, 54 NORMAL = 1, 55 CENTER=2, 56 DELAYED_SHUTDOWN=3, 57 nil 58 } 59 60 ---------------------------------------------------------- 61 ---资源管理器 62 local unloadResource = {} 63 64 function uinode:unloadCustomResources() 65 local res = self:__getCustomResources() 66 if res ~= nil and #res > 0 then 67 xse.base.unloadTextures(res) 68 end 69 end 70 71 function uinode:__getCustomResources() 72 if self.getCustomResources == nil then return {} end 73 local resources = self:getCustomResources() 74 return resources or {} 75 end 76 77 function uinode:starLoadResource() 78 if self.mask == nil then 79 self.mask = xse.base.loadCCBI("waitting.ccbi",false) 80 xse.base.Scene:addChild(self.mask,999999999) 81 end 82 end 83 84 function uinode:endLoadResource() 85 xse.base.Scene:removeChild(self.mask) 86 self.mask = nil 87 end 88 89 ---加载资源 90 function uinode:loadResource(onloadComplate) 91 if uinode.__getCustomResources ~= nil then 92 local res = self:__getCustomResources() 93 if res == nil or #res == 0 then onloadComplate() 94 else 95 local __id = nil 96 local __index = 1 97 local __timerCounter = 1 98 self:starLoadResource() 99 local loaded = false100 __id = xse.base.timer.tick.add(function()101 if loaded ~= true then loaded = true102 for var=1, #res do103 cc.Director:getInstance():getTextureCache():addImageAsync(res[var],104 function()105 log("set load command :"..res[var])106 __index = __index + 1107 end)108 end109 end110 111 __timerCounter = __timerCounter + 1112 if __index >= #res and __timerCounter > 100 then113 onloadComplate()114 self:endLoadResource()115 xse.base.timer.tick.remove(__id)116 end117 end)118 end119 elseif onloadComplate~= nil then120 onloadComplate()121 end122 end123 124 -------------------------------------------------------------------------125 --帮助函数私有成员函数126 127 ---加载CCBI文件128 --@param nodestr string 要加载的资源名字,不包含后缀名129 --@return #cc.Node 一个node节点130 function uinode:loadCCBI(nodestr)131 assert(nodestr~=nil and type(nodestr)=="string","param nodestr must a string type")132 -- local node = xse.base.loadScene(nodestr,nil,self:getShowModel()== uinode.showModel.CENTER)133 local node = xse.base.loadScene(nodestr,nil)134 return node135 end136 137 ---为当前对象绑定一个ccbi138 --@param nodestr string 要加载的资源名字,不包含后缀名139 --@return cc.Node 当前对象绑定的节点140 function uinode:bindCCBI(nodestr)141 if self.node~=nil then142 local parent = self.node:getParent()143 if parent then parent:removeChild(parent) end144 self.node = nil145 end146 147 if self.node == nil then148 self:registeUICallBack()149 self.node = self:loadCCBI(nodestr)150 self.node.__bindToInstance = self151 end152 return self.node153 end154 155 ---绑定脚本到ccbi上156 function uinode:bindScriptToNode(node)157 node.__bindToInstance = self158 end159 160 ---卸载ccbi文件161 --@param nodestr string 要卸载的资源名字,不包含后缀名162 function uinode:unloadCCBI(nodestr)163 assert("false","暂时不支持的方法")164 end165 166 ---重新加载CCBI文件167 --@param nodestr string 要加载的资源名字,不包含后缀名168 function uinode:reloadCCBI()169 local parent = self.node:getParent()170 if parent ~= nil then parent:removeChild(self.node)end171 self:bindCCBI(self:getBindUINodeStr())172 end173 174 ---显示界面函数175 function uinode:show(onshowComplate)176 assert(onshowComplate,"callbakc is nil value")177 switch(self:getShowModel(),{178 179 [uinode.showModel.NOTADDTO_CONTENT] = function()180 ---不设置为添加到窗口中,就直接调用aftershow181 self:afterShow()182 end,183 184 [uinode.showModel.NORMAL] = function()185 ---添加到界面上186 xse.base.show(nil,self.node)187 ---显示动画188 xse.base.animal.show(189 self.node,190 nil,191 function() onshowComplate() ; self:afterShow() end192 )193 end,194 195 [uinode.showModel.CENTER] = function()196 onshowComplate();197 xse.base.animal.showOnCenter(self.node,nil,198 function() self:close(); end,199 self,200 function ()201 self:afterShow();202 end)203 end,204 205 [uinode.showModel.DELAYED_SHUTDOWN] = function()206 onshowComplate();207 xse.base.show(nil,self.node);208 end,209 210 [uinode.showModel.NONE] = function()211 xse.base.animal.show(self.node,xse.base.Scene,212 function()213 onshowComplate();214 self:afterShow();215 end, false216 ) end,217 218 ["default"] = function()219 xse.base.animal.show(self.node,220 nil,221 function() onshowComplate();self:afterShow() end)222 end,223 })224 225 self:endLoadResource()226 end227 228 function uinode:afterShow()229 230 end231 232 function uinode:processClose()233 self.moreNode = nil234 switch(self:getShowModel(),{235 [uinode.showModel.NORMAL] = function()236 xse.base.hide(nil,self.node,function()237 self:after_close()238 end);239 self.node = nil;240 end,241 [uinode.showModel.CENTER] = function()242 xse.base.hide(nil,self.node,function()243 self:after_close()244 end);245 self.node = nil;246 end,247 [uinode.showModel.DELAYED_SHUTDOWN] = function()248 local action = cc.Sequence:create(cc.DelayTime:create(1),cc.CallFunc:create(function()249 xse.base.hide(nil,self.node,function() self:after_close() end);250 self.node = nil;251 end))252 self.node:runAction(action)253 end,254 ["default"] = function()255 xse.base.hide(nil,self.node,function()256 self:after_close()257 end);258 self.node = nil;259 end,260 })261 262 263 end264 265 function uinode:after_close()266 self:unloadCustomResources()267 end268 269 ---关闭界面函数270 function uinode:close(sender)271 log("#close ".. tostring(self:getHashCode()))272 ---在关闭前的回掉273 if self.before_close ~=nil and type(self.before_close) == "function" then274 self:before_close(function(rd,sn,sd)275 if type(sender) == "function" then sender()end276 end)277 self:processClose()278 else279 if type(sender) == "function" then sender() end280 self:processClose()281 end282 self:unregisteUICallBack() --避免在关闭的时候还有操作造成无法处理的bug283 end284 285 ---注册自己定义的ui回调事件286 function uinode:setCustomUiCallBack()287 ---不做任何事情,留给子类去处理288 end289 290 ---注册当前node 的回调事件291 function uinode:registeUICallBack()292 ---自定义事件注册293 self:setCustomUiCallBack()294 ---295 local name = self:getName()296 if name ~="unkonw" then297 for key, var in pairs(self) do298 if type(var)== "function"then299 xse.base.addEventSupportA(name,key,300 function(sender)301 assert(sender~=nil,"sender is nil value")302 local __callinstance = nil303 local tempsender = sender304 local obj = sender305 while sender ~= nil and (type(sender)== "table" or type(sender)== "userdata") do306 assert(not (__callinstance and sender.__bindToInstance),"子节点界面不应该单独绑定到uinode上")307 if sender.__bindToInstance~= nil then308 __callinstance = sender.__bindToInstance309 break;310 end311 sender = sender:getParent()312 end313 314 if __callinstance~=nil then315 local fun = __callinstance[key]316 fun(__callinstance,tempsender)317 return318 end319 320 assert(false,"Have not found the bound script logic in all parent nodes,")321 end)322 end323 end324 end325 end326 327 ---注册当前node ui 的回调事件328 function uinode:unregisteUICallBack()329 local name = self:getName()330 if name ~="unkonw" then331 for key, var in pairs(self) do332 if type(var)== "function"then333 ---取消事件注册334 xse.base.addEventSupportA(name,key,nil)335 end336 end337 end338 end339 340 ---------------------------------------------------------------------------341 --业务接口342 343 ---禁止重写这个函数®344 function uinode:open(openArgs)345 if self.UserGuidelineSupportConfig then346 self.userGuideLineConfigKey = xse.base.random()347 userGuidelineManager:addUserGuidelineSupportA(self,self.userGuideLineConfigKey)348 end349 350 self:loadResource(function()351 local ccbstr = self:getBindUINodeStr()352 assert(ccbstr,"self:getBindUINodeStr()返回的数据不合法")353 self:bindCCBI(ccbstr)---绑定界面354 355 local function init(self)356 self.__openArgs = openArgs357 ---发送网络命令358 if self.getCmdStr and type(self.getCmdStr) == "function" then359 local cmdstr = self:getCmdStr()360 local dt = self:getCmdData()361 ---发送网络通信362 local remoteTask,protocal,command = require "remoteTask",require "protocal",require "command"363 assert(cmdstr,"Rewrite getCmdStr function, but the data returned is empty.")364 protocal:adddt(command[cmdstr],dt)365 local sn = remoteTask.add(protocal,communication.type.tcp,function(rd,sn,sd,self)366 if self.onRemoteAck then self:onRemoteAck(rd) end367 self:show(function()368 self:on_initUI(self.node,self.__openArgs,rd)369 end)370 end,nil,self)371 372 else373 self:on_initUI(self.node,self.__openArgs,rd)374 self:show(function()375 --self:on_iniself:on_initUI(self.node,self.__openArgs,rd)tUI(self.node,self.__openArgs,rd)376 end)377 end378 end379 380 ---DEBUG模式下调用初始化一些必要的基础数据381 debugCallFun(function()382 require("tcpExt")383 ---刷新全部依赖的数据384 tcpTaskQueue({385 {cmd = "WORLD_INIT",dt = {},callback = function(rd,sn,sd) init(self) end,errfun = nil},386 {cmd = "COMPANY_INIT",dt = {},callback = function(rd,sn,sd) end,errfun = nil},387 })388 end,nil)389 390 releaseCallFun(init,self)391 end)392 end393 394 ---绑定界面函数 [可重写]395 -- @return #string 要绑定的界面,不包含后缀名396 function uinode:getBindUINodeStr()397 assert(false,"必须实现要绑定的界面")398 return nil399 end400 401 ---显示模式 [可选函数]402 --@return #uinode.showModel 现实的模式403 --PS:[显示模式,不实现是直接打开。不会居中]404 function uinode:getShowModel()405 return uinode.showModel.NORMAL406 end407 408 ---打开界面前要执行网络操作[可选函数]409 --@return cmdstr string410 --function uinode:getCmdStr()411 -- return nil412 --end413 --uinode.getCmdStr = nil414 415 ---发送网络命令需要的数据416 --@return table #table,加载界面前发送网络命令时需要的数据417 function uinode:getCmdData()418 return {}419 end420 421 --422 423 424 ---初始化界面上的相关信息[可选函数]425 --@param node cc.Node 界面已绑定好的节点426 --@param openArgs unknow open方法穿过来的数据427 --@param networkArgs unknow 没有使用网络函数为nil,使用了网络函数:就为网络返回的数据428 --@return nil429 function uinode:on_initUI(node,openArgs,networkArgs)430 -- self:on_initUI(node, opendArgs, networkArgs);431 end432 433 ---关闭界面前要进行网络通信 [可选函数]434 --@param networkACKCallBack function(rd,sn,sd) 网络成功后的回掉函数435 --@return nil436 function uinode:before_close(networkACKCallBack)437 return false438 end439 440 uinode.before_close = nil441 442 return uinode
使用DEMO
local story = {}require("depend")require("tableViewExt")require("uinode")local tabView = require "TabView"local text = require("richtext")inheritanceA(story,object,"object")inheritanceA(story,uinode,"uinode")--uinode abstract functionimplementInterface(story,"getShowModel",function(self) return uinode.showModel.NONE end )implementInterface(story,"getBindUINodeStr",function(self) return "start01" end )implementInterface(story,"getName",function(self) return "message_layer" end )implementInterface(story,"on_initUI",function(self,node,openArgs,networkArgs) self:init(node,openArgs,networkArgs) end )function story:init() cc.SimpleAudioEngine:getInstance():stopMusic() cc.SimpleAudioEngine:getInstance():playMusic("storyBackgroudn.mp3",true) local daytime = cc.DelayTime:create(1) --TODO::增加语言 self.fontConfig = { {fontSize = 30,str="23世界末,第三次世界大战\"能源战\"爆发。\"联军\"为了维持庞大的军费开支,开始将阿波罗-188号飞船用于商用。一些富商为了躲避战火纷纷变卖资产换取船票前往“开普勒”,而您,曾经闻名于世的一代商业传奇人物,也随着这波人流,开启了一段新的征程。",color = xse.color.GREEN}} local funAction = cc.CallFunc:create(function() self.text = richtext.playMessage(self,self.node, self.fontConfig,function() local daytime2 = cc.DelayTime:create(1) local nextaction = cc.CallFunc:create(function() xse.base.setCCBottonOnClick(self.node:getChildByTag(200),function() self:swithNode() end,self) --self:swithNode() self.node:getChildByTag(200):setVisible(true) end) self.node:runAction(cc.Sequence:create(daytime2,nextaction)) end) end) self.node:runAction(cc.Sequence:create(daytime,funAction)) self.node:getChildByTag(200):setVisible(false)-- self.text=richtext.playMessage(self,self.node, self.fontConfig)-- xse.base.setCCBottonOnClick(self.node:getChildByTag(200),function() self:swithNode() end,self)endfunction story:swithNode() local layer = self.node:getParent() self.text:getParent():removeChild(self.text) layer:removeChild(self.node) self.node = xse.base.loadCCBI("start02.ccbi") xse.base.show(layer,self.node) local daytime2 = cc.DelayTime:create(8) local nextaction = cc.CallFunc:create(function() local instance = require("citadel") instance:new():open() end) self.node:runAction(cc.Sequence:create(daytime2,nextaction))endreturn story