这篇文章会讲解cocosbuilder的一些问题,会用到cocosbuilder的相关知识,如果您对cocosbuilder 不熟悉的话建议您先学习cocosbuilder!
http://blog.justbilt.com/549/
使用过cocosbuilder的同学都知道每一个界面会对应一个.ccb文件,将好几个界面都重复拥有的东西单独制作一个ccb界面,然后以ccb控件的方式加入到其他界面中.
1.如下,我的游戏中暂停,胜利,失败界面都会有一个分享的东西.
如上图所示,如果我每个界面都去添加这些素材,按钮什么的,必定十分费神费力,遂我们不如将它单独作为一个页面,然后让每个用到的页面去引用它!
2.如下图所示,我们创建一个单独的页面,命名为SharedLayer.ccb(点击查看大图):
对于这个界面,我们需要注意到一下几点:
3.完成后我们就可以在其它界面引用SharedLayer.ccb界面了(点击查看大图):
对于这个界面,步骤如下:
1.在这里先要说下小弟的文件布局:
不知大家能否看的懂?主要就是
2.下面让我们看下程序中的加载吧!
1).对于普通的ccb的加载可以用到下面的这个函数:
1
2
3
4
5
6
7
8
9
10
|
CCNode
*
createCCBLayer
(
LPCSTR
szClass
,
CCNodeLoader
*
pLoader
,
LPCSTR
szName
,
CCNode
*
pOwner
)
{
CCNodeLoaderLibrary
*
ccNodeLoaderLibrary
=
CCNodeLoaderLibrary
::
newDefaultCCNodeLoaderLibrary
(
)
;
cocos2d
::
extension
::
CCBReader
*
ccbReader
=
NULL
;
ccNodeLoaderLibrary
->
registerCCNodeLoader
(
szClass
,
pLoader
)
;
//注册类名和loader
ccbReader
=
new
cocos2d
::
extension
::
CCBReader
(
ccNodeLoaderLibrary
)
;
ccbReader
->
autorelease
(
)
;
ccbReader
->
setCCBRootPath
(
"ccbResources"
)
;
//因为我的资源没有位于根目录中,所以需要设置下ccb的root路径!
return
ccbReader
->
readNodeGraphFromFile
(
szName
,
pOwner
)
;
}
|
2).加载的时候调用如下代码即可:
1
2
|
CCNode
*
pLayer
=
createCCBLayer
(
"CPauseLayer"
,
CPauseLayerLoader
::
loader
(
)
,
"PauseLayer.ccbi"
,
CCDirector
::
sharedDirector
(
)
->
getRunningScene
(
)
)
;
pScene
->
addChild
(
pLayer
)
;
|
3).但是我们现在的这个PauseLayer还包含着另一个界面,所以只注册一个类名和loader是不行的!于是貌似我们把函数改成如下的就OK了?
1
2
3
4
5
6
7
8
9
10
11
|
CCNode
*
CLoadingScene
::
createCCBLayer
(
LPCSTR
szClass1
,
cocos2d
::
extension
::
CCNodeLoader
*
pLoader1
,
LPCSTR
szClass2
,
cocos2d
::
extension
::
CCNodeLoader
*
pLoader2
,
LPCSTR
szName
,
CCNode
*
pOwner
)
{
CCNodeLoaderLibrary
*
ccNodeLoaderLibrary
=
CCNodeLoaderLibrary
::
newDefaultCCNodeLoaderLibrary
(
)
;
cocos2d
::
extension
::
CCBReader
*
ccbReader
=
NULL
;
ccNodeLoaderLibrary
->
registerCCNodeLoader
(
szClass1
,
pLoader1
)
;
//类1 和loader1
ccNodeLoaderLibrary
->
registerCCNodeLoader
(
szClass2
,
pLoader2
)
;
//类2 和loader2
ccbReader
=
new
cocos2d
::
extension
::
CCBReader
(
ccNodeLoaderLibrary
)
;
ccbReader
->
setCCBRootPath
(
"ccbResources"
)
;
ccbReader
->
autorelease
(
)
;
return
ccbReader
->
readNodeGraphFromFile
(
szName
,
pOwner
)
;
}
|
4).但是结果是你只能得到崩溃!这个问题困扰我足足有1整天时间,最后一直断点追中的很深才明白的!原来ccbreader内部也是按照如下的方式去处理CCBFile类型的控件的:
1
2
3
4
|
cocos2d
::
extension
::
CCBReader
*
ccbReader
=
NULL
;
ccbReader
=
new
cocos2d
::
extension
::
CCBReader
(
ccNodeLoaderLibrary
)
;
ccbReader
->
autorelease
(
)
;
return
ccbReader
->
readNodeGraphFromFile
(
szName
,
pOwner
)
;
|
只不过它少了这一句:
1
|
ccbReader
->
setCCBRootPath
(
"ccbResources"
)
;
|
于是资源位置就会错误,自然会崩溃!
5).解决这个问题有如下两个解决方案:
1.修改ccbreader源代码:将setCCBRootPath内部的mCCBRootPath改为静态变量,这样所有的ccbreader就会公用一个rootpath!
2.彻底在程序中抛弃:ccbReader->setCCBRootPath(“ccbResources”)这行代码!
不想改源代码,所以我采用的第二种解决方案!最简单的做法是将ccbResources目录中的文件全部拷贝出来放在Resources目录下就大功告成!但是我们的Resources目录下还可能防其他的东西啊,比如声音文件,数据文件,及游戏中的图片文件,这样子会很乱,而且cocosbuilder很容易出现递归查找的错误!
最终做法如下,将ccbResources和ipad文件夹同时放在Resources路径下,设置文件查找路径为:
1
2
3
4
|
vector
<
string
>
searchPath
=
CCFileUtils
::
sharedFileUtils
(
)
->
getSearchPaths
(
)
;
searchPath
.
insert
(
searchPath
.
begin
(
)
,
"ipad"
)
;
searchPath
.
insert
(
searchPath
.
begin
(
)
,
"ccbResources"
)
;
CCFileUtils
::
sharedFileUtils
(
)
->
setSearchPaths
(
searchPath
)
;
|
这样我将游戏中的所有文件全放在iapd路径下,而cocosbuilder的导出文件全放在ccbResources目录下!
设置:cocosbuilder的导出路径为:../Resources/ccbResources
文件布局截图:
文章下半部分比较晦涩,有哪里看不太明白,欢迎指出!!!