学习cocos2d-x也有一段时间了,也看了些东西,写了些东西,但都是不成系统的,这次想整体的了解下cocos2d-x,正好也提供了一个testcpp例子,所以顺便也写下我的一些见解,水平有限,期待您纠正我的错误理解或不懂的地方。
本文版本是2.14!
TessCPP程序截图如下:2个CCMenu,一个列举了很多个粒子名称的菜单,一个关闭菜单
TestCpp工程在G:\cocos2d-x-2.1.4\cocos2d-x-2.1.4\samples\Cpp\TestCpp路径下
有下列几个文件夹,我们只需要关注
Classes :头文件和CPP文件均在这个文件夹下!
proj.win32:main文件以及vs工程文件
Resources:顾名思义,例子程序用到的一些资源都在里面
Classes文件结构如下:上面那些文件夹,都是单个的例子的文件,现在我们主要看该目录下的头文件和CPP文件。
AppDelegate:无须多解释了吧!
tests.h:保存了例子的名字
testResource.h 保存了用到资源路径
controller:控制图层,也就是启动程序看到的界面
VisibleRect:可见区域,用于获取屏幕9个关键点的坐标,为了屏幕适配,按比例确定程序中各元素的位置
testBasic:测试例子的基类,主要是方便场景的替换。
下面详细看下代码!
首先是AppDelegate文件,找到下列函数,从main入口函数开始CCApplication::sharedApplication()->run()就是进入到这里!
bool AppDelegate::applicationDidFinishLaunching()
{
// As an example, load config file
// XXX: This should be loaded before the Director is initialized,
// XXX: but at this point, the director is already initialized
CCConfiguration::sharedConfiguration()->loadConfigFile("configs/config-example.plist");
// initialize director
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();
CCSize designSize = CCSizeMake(480, 320);
CCFileUtils* pFileUtils = CCFileUtils::sharedFileUtils();
if (screenSize.height > 320)//这一块主要是用来做屏幕适配的
{
CCSize resourceSize = CCSizeMake(960, 640);
std::vector<std::string> searchPaths;
searchPaths.push_back("hd");
pFileUtils->setSearchPaths(searchPaths);
pDirector->setContentScaleFactor(resourceSize.height/designSize.height);
}
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionNoBorder);
CCScene * pScene = CCScene::create();
CCLayer * pLayer = new TestController();//例子的控制图层,也就是我们一开始看到的界面
pLayer->autorelease();
pScene->addChild(pLayer);
pDirector->runWithScene(pScene);
return true;
}
然后进入到TestController文件,首先看下头文件
class TestController : public CCLayer
{
public:
TestController();
~TestController();
void menuCallback(CCObject * pSender);//这就是中间那一系列例子菜单的响应函数
void closeCallback(CCObject * pSender);//最左边的关闭按钮的响应函数
virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);//触屏开始
virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);//触屏移动
private:
CCPoint m_tBeginPos;//触屏开始点击的坐标
CCMenu* m_pItemMenu;//例子菜单
};
TestController初始化放到了构造函数里头
TestController::TestController()
: m_tBeginPos(CCPointZero)
{
// add close menu
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(s_pPathClose, s_pPathClose, this, menu_selector(TestController::closeCallback) );
CCMenu* pMenu =CCMenu::create(pCloseItem, NULL);
pMenu->setPosition( CCPointZero );
pCloseItem->setPosition(ccp( VisibleRect::right().x - 30, VisibleRect::top().y - 30));
// add menu items for tests
m_pItemMenu = CCMenu::create();
for (int i = 0; i < TESTS_COUNT; ++i)//依次初始化例子菜单项
{
// #if (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)
// CCLabelBMFont* label = CCLabelBMFont::create(g_aTestNames[i].c_str(), "fonts/arial16.fnt");
// #else
CCLabelTTF* label = CCLabelTTF::create(g_aTestNames[i].c_str(), "Arial", 24);
// #endif
CCMenuItemLabel* pMenuItem = CCMenuItemLabel::create(label, this, menu_selector(TestController::menuCallback));
m_pItemMenu->addChild(pMenuItem, i + 10000);
pMenuItem->setPosition( ccp( VisibleRect::center().x, (VisibleRect::top().y - (i + 1) * LINE_SPACE) ));
}
m_pItemMenu->setContentSize(CCSizeMake(VisibleRect::getVisibleRect().size.width, (TESTS_COUNT + 1) * (LINE_SPACE)));
m_pItemMenu->setPosition(s_tCurPos);//静态变量,用于保存例子主菜单的当前位置
addChild(m_pItemMenu);
setTouchEnabled(true);//允许触屏
addChild(pMenu, 1);
}
下面是菜单项的响应函数,在这里面进行场景的切换
void TestController::menuCallback(CCObject * pSender)
{
// get the userdata, it's the index of the menu item clicked
CCMenuItem* pMenuItem = (CCMenuItem *)(pSender);
int nIdx = pMenuItem->getZOrder() - 10000;//获取菜单项ID
// create the test scene and run it
TestScene* pScene = CreateTestScene(nIdx);//这是个静态函数,方便获取各粒子的图层
if (pScene)
{
pScene->runThisTest();
pScene->release();
}
}
在controller.cpp文件中定义了些宏和静态函数,方便我们使用
#define LINE_SPACE 40 //菜单项之间的间距
static CCPoint s_tCurPos = CCPointZero;//主菜单的当前坐标,估计在各粒子中会用到
static TestScene* CreateTestScene(int nIdx)//根据id获取测试例子的图层(layer)
最后我们来看下testBasic测试基类
#ifndef _TEST_BASIC_H_
#define _TEST_BASIC_H_
#include "cocos2d.h"
#include "VisibleRect.h"
USING_NS_CC;
using namespace std;
class TestScene : public CCScene
{
public:
TestScene(bool bPortrait = false);
virtual void onEnter();//在这里帮每个例子加了个返回主菜单的按钮,也就是我们在右下方看到的MainMenu
virtual void runThisTest() = 0;
// The CallBack for back to the main menu scene
virtual void MainMenuCallback(CCObject* pSender);//返回住菜单的响应函数
};
typedef CCLayer* (*NEWTESTFUNC)();//这里定义了些宏函数,有些还不是很清楚
#define TESTLAYER_CREATE_FUNC(className) \ //创建例子图层,其实也就是我们CREATE_FUNC
static CCLayer* create##className() \
{ return new className(); }
#define CF(className) create##className
#endif
这些宏函数将会在接下来用到!