参考http://blog.csdn.net/honghaier/article/details/8130947
controller.h/cpp:示例场景管理类TestController,用于显示所有示例的菜单。
testBasic.h/cpp:示例场景基类TestScene,用于返回到主界面场景。
先说个宏:
#define NS_CC_BEGIN namespace cocos2d {
#define NS_CC_END }
#define USING_NS_CC usingnamespace cocos2d
当然如果不用这些宏的话,可以直接带上cocos2d::
在AppDelegate.cpp中的boolAppDelegate::applicationDid。FinishLaunching()函数中创建场景并运行场景
bool AppDelegate::applicationDidFinishLaunching()
{
CCScene * pScene = CCScene::create();
//实例化一个TestController,它是一个CCLayer。
CCLayer * pLayer = new TestController();
//设置由内存管理器来进行自动回收,不必手动DELETE
pLayer->autorelease();
//将它放置到场景中
pScene->addChild(pLayer);
//运行这个新创建的场景。
pDirector->runWithScene(pScene);</span>
}
在controller.cpp
//构造函数
TestScene::TestScene(bool bPortrait)
{
CCScene::init();
}
//场景被加载时的回调函数
void TestScene::onEnter()
{
CCScene::onEnter();
//创建一个文字标签,显示“MainMenu”字符串
CCLabelTTF* label = CCLabelTTF::create("MainMenu", "Arial", 20);
//增加一个菜单标签,设定其被按下时的回调函数,用于返回到主界面
CCMenuItemLabel* pMenuItem = CCMenuItemLabel::create(label, this, menu_selector(TestScene::MainMenuCallback));
//将菜单标签加入创建的菜单中,并设置相应位置。
CCMenu* pMenu =CCMenu::create(pMenuItem, NULL);
CCSize s = CCDirector::sharedDirector()->getWinSize();
pMenu->setPosition( CCPointZero );
pMenuItem->setPosition( CCPointMake( s.width - 50, 25) );
//将菜单放入场景中。
addChild(pMenu, 1);
}
//菜单标签被按下时的响应函数,返回主菜单功能
void TestScene::MainMenuCallback(CCObject* pSender)
{
//新创建一个场景。
CCScene* pScene = CCScene::create();
//新创建一个TestController对象
CCLayer* pLayer = new TestController();
pLayer->autorelease();
//将它放入新创建的场景中并运行。
pScene->addChild(pLayer);
CCDirector::sharedDirector()->replaceScene(pScene);
}
在controller.cpp有关主菜单的操作
//主菜单的构造
TestController::TestController()
: m_tBeginPos(CCPointZero)
{
//新建一个测试项菜单,将所有代表测试场景的菜单标签项加入菜单
m_pItemMenu = CCMenu::create();
for (int i = 0; i < TESTS_COUNT; ++i)
{
//将代表测试场景的菜单标签加入菜单中,以i+10000的值做为Z值。
m_pItemMenu->addChild(pMenuItem, i + 10000);
//设置代表测试场景的菜单标签在测试项菜单层的位置
pMenuItem->setPosition( CCPointMake( s.width / 2, (s.height - (i + 1) * LINE_SPACE) ));
}
}
//点击菜单选项
void TestController::menuCallback(CCObject * pSender)
{
// 取得菜单项
CCMenuItem* pMenuItem = (CCMenuItem *)(pSender);
//取得Z值,减10000算出是第几个菜单项
int nIdx = pMenuItem->getZOrder() - 10000;
//创建相应的场景
TestScene* pScene = CreateTestScene(nIdx);
if (pScene)
{ //运行当前测试场景
//CCDirector::sharedDirector()->purgeCachedData();
//中间有用到上面这个函数来清空缓存
pScene->runThisTest();
//runThisTest调用中有用到retain()会对其引用计数加1变为2,这里做一次引用计数减1操作,以保证后面再释放场景时可以正常的释放。
pScene->release();
}
}
void TestController::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
CCSetIterator it = pTouches->begin();
CCTouch* touch = (CCTouch*)(*it);
m_tBeginPos = touch->getLocation();
}
//按住鼠标拖动时触发 处理菜单下拉功能
void TestController::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)
{
//获取第一个触点位置
CCSetIterator it = pTouches->begin();
CCTouch* touch = (CCTouch*)(*it);
//取得这个位置与上一帧移动的Y值之差,即在纵方向的偏移。
CCPoint touchLocation = touch->getLocation();
float nMoveY = touchLocation.y - m_tBeginPos.y;
//计算菜单在纵方向上也移动相应值后的新位置。
CCPoint curPos = m_pItemMenu->getPosition();
CCPoint nextPos = ccp(curPos.x, curPos.y + nMoveY);
//这里对新位置的有效范围做个限定
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
if (nextPos.y < 0.0f)
{
m_pItemMenu->setPosition(CCPointZero);
return;
}
if (nextPos.y > ((TESTS_COUNT + 1)* LINE_SPACE - winSize.height))
{
m_pItemMenu->setPosition(ccp(0, ((TESTS_COUNT + 1)* LINE_SPACE - winSize.height)));
return;
}
//更新菜单到新位置
m_pItemMenu->setPosition(nextPos);
//记录当前位置为旧位置。
m_tBeginPos = touchLocation;
s_tCurPos = nextPos;
}
<1> 调用CCDirector::sharedDirector()->purgeCachedData()清空缓存。
<2> 新建场景。
<3> 调用CCDirector::sharedDirector()->replaceScene(this)替换新场景。
注意:不要在节点初始化的init函数中调用replaceScene函数。导演类不允许在一个节点初始化的调用场景替换,
否则会导致程序崩溃。
这里说一下压入场景(pushScene)和弹出场景(popScene)。它们都可以用来显示场景和保留当前场景并显示新场景;不同的是它们不把旧场景从内存中释放掉,这样可以提高加载速度,这时需要注意,如果场景比较大的话,会消耗较多的内存,建议采用replaceScene函数。
特殊场景类:切换时带有切换效果
即在CCTransitionScene子类的create函数,生成相应场景。当然,不同效果的使用方法略有不同。
然后,通过replaceScene函数启动场景,也就是说给这个场景加了一个外包装类,然后再启动。那么,这个场景
就不是直接显示了,而是在场景的效果动画播完以后进入场景,起到了过渡的效果。
一般情况,CCTransitionScene子类的create函数有两个参数。第一个参数是特效的切换时间,直接生成一个
CCTime类即可,例子中设定的时间是1 ~ 2s,对于很多场景的显示都很舒服,你也可以根据你的要求修改切换的时
间;第二个参数是要进入的场景。有的类会有第三个参数,如下图所示。
其中,CCTransitionPageTurn类需要先设置摄像机,使用如下代码:
- CCDirector::sharedDirector()->setDepthTest(true);
有三种特效需要检测OpenGL版本是否支持,如下图表所示。使用如下代码检查,如果为真则不支持:
- CCConfiguration::sharedConfiguration()->getGlesVersion() <= GLES_VER_1_0
tests项目的TransitionTest文件夹中的是场景切换的示例。切换场景动画的使用步骤如下。
<1> 新建场景。
<2> 根据需要的新建场景的切换动画选择CCTransitionScene子类,通过create将之前建的场景传入其中,并设置其
他参数。
<3> 调用CCDirector::sharedDirector()->replaceScene(第2步中定义的CCTransitionScene的子类)替换场景。