作为程序猿还是要代码来说事的,现在开始进入到具体的代码中来。国际惯例HelloWorld打头阵,我也不能免这个俗。
Win32入口函数中主要代码如下:
main.cpp// 创建应用实例 AppDelegate app; //创建游戏窗口并设置窗口大小 CCEGLView* eglView = CCEGLView::sharedOpenGLView(); eglView->setFrameSize(2048, 1536); eglView->setFrameZoomFactor(0.4f); //分辨率的0.4倍 return CCApplication::sharedApplication()->run();
语句AppDelegate app 将创建一个应用程序实例,类AppDelegate 继承自CCApplication,此处将调用到分类CCApplication的构造函数。接下来的两句代码创建了游戏窗口并设置了它的大小。因为我们电脑显示器分辨率一般都不高(远远没达到2048X1536),所有使用了eglView->setFrameZoomFactor(0.4f)缩放窗口。最后使用CCApplication的sharedApplication方法获取一个实例运行。
初看这部分代码不明白为什么已经创建了一个继承自CCApplication的实例,还在最后使用sharedApplication方法创建实例。其实最后一句已经不是在创建实例而是在获取已经创建的实例。这是由C++语法特性确定的,在调用AppDelegate 的无参数构造函数的时候首先会调用父类的无参数构造。我们到父类CCApplication构造函数看看就明了:
CCApplication::CCApplication() : m_hInstance(NULL) , m_hAccelTable(NULL) { m_hInstance = GetModuleHandle(NULL); m_nAnimationInterval.QuadPart = 0; CC_ASSERT(! sm_pSharedApplication); sm_pSharedApplication = this; // 将当前实例保存起来 } CCApplication* CCApplication::sharedApplication() { CC_ASSERT(sm_pSharedApplication); return sm_pSharedApplication; }
下面来看看AppDelegate重载CCApplication的三个方法:
applicationDidEnterBackground() 当游戏窗口进入后台时所要做的处理,比如手机有一个电话进来的时候,游戏窗口就回转到后台。
applicationWillEnterForeground() 当游戏窗口恢复到前台的时候要做的工作。
applicationDidFinishLaunching() 当启动游戏窗口完成后所要做的工作。
在HelloWorld程序中,前两个方法就是调用父类中相应的方法,下面我们重点来看看最后一个,代码如下:
bool AppDelegate::applicationDidFinishLaunching() { // 创建导演实例 CCDirector* pDirector = CCDirector::sharedDirector(); // 在main中已经创建过,者里仅仅是获取已经创建的实例
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); // 将游戏窗口传递个导演实例,导演绘制的内容就在该窗口上
pDirector->setOpenGLView(pEGLView); //设置帧显示模式 pDirector->setDisplayStats(true); // 设置每秒60帧 pDirector->setAnimationInterval(1.0 / 60); // 创建一个场景对象
CCScene *pScene = HelloWorld::scene(); // 让导演绘制这个场景 pDirector->runWithScene(pScene); return true; }
代码已经注释的够清楚就不多解释,Demo中的代码我删除了设置资源路径那部分。下面再来看看场景是如何创建出来的
CCScene* HelloWorld::scene() { //创建一个场景实例,它讲由引擎自动释放 CCScene *scene = CCScene::create(); // 创建一个HelloWorld类型的图层对象 HelloWorld *layer = HelloWorld::create(); // 将图层添加到场景中 scene->addChild(layer); return scene; }
上面代码重点就这句HelloWorld *layer = HelloWorld::create() ,create从和而来还要看看头文件这句
// implement the "static node()" method manually CREATE_FUNC(HelloWorld); //
这个宏展开会调用init方法,所以这个类中最重要的就是他了。init方法包含了HelloWorld程序中的所有绘制逻辑。
bool HelloWorld::init() { //调用基类的init方法 if ( !CCLayer::init() ) { return false; } CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin(); //用图片创建一个关闭菜单项,并为其关联回调函数 CCMenuItemImage *pCloseItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback)); // pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 , origin.y + pCloseItem->getContentSize().height/2)); // 根据菜单项创建一个菜单并添加到图层中 CCMenu* pMenu = CCMenu::create(pCloseItem, NULL); pMenu->setPosition(CCPointZero); this->addChild(pMenu, 1); //创建一个显示"Hello World"的标签 CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", TITLE_FONT_SIZE); // 设置显示位置为屏幕中央 pLabel->setPosition(ccp(origin.x + visibleSize.width/2, origin.y + visibleSize.height - pLabel->getContentSize().height)); // add the label as a child to this layer this->addChild(pLabel, 1); // 使用图片创建一个精灵实例 CCSprite* pSprite = CCSprite::create("HelloWorld.png"); pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); this->addChild(pSprite, 0); return true; }
运行效果像这样(windows环境搭建很容易,请到网上搜索)