对应第2章《不离不弃的HelloWorld》。
一如既往的HelloWorld。
在Cocos2d-x的解压缩目录下找到cocos2d-win32.vc2010.sln文件,双击打开,可以看到Cocos2d-x的官方Demo源代码,这里包含了很多例子的工程,熟悉研究这些例子会收获很多(其实这就是最好的教程,不过枯燥,但有味道)。在【解决方案资源管理器】的【project-cpp】中找到工程【HelloCpp】,查看main.cpp中的代码
CCEGLView* eglView = CCEGLView::sharedOpenGLView(); eglView->setViewName("HelloCpp"); eglView->setFrameSize(2048, 1536); // The resolution of ipad3 is very large. In general, PC's resolution is smaller than it. // So we need to invoke 'setFrameZoomFactor'(only valid on desktop(win32, mac, linux)) to make the window smaller. eglView->setFrameZoomFactor(0.4f);
一、解决编译报错的方案
1、复制源文件
(1) 在Cocos2d-x的根目录中,找到”cocos2dx“和”CocosDenshion“文件夹,将其复制到新建的项目目录下。
(2)在Cocos2d-x的根目录中,找到”Debug.win32“文件夹,覆盖掉新建项目的该文件夹(其实里面有很多库文件是用不到的)。
2、修改项目配置
(1)仍然需要复制Debug.win32文件夹。
(2)在项目属性对话框中,依次选择【配置属性】→【C/C++】,编辑右侧的【附加包含目录】,可以看到附加包含目录默认都是类似”$(SolutionDir)cocos2dx“的形式,我们需要将所有的$(SolutionDir)替换成Cocos2d-x的根目录(最后要添加/)。
在熟悉Cocos2d-x游戏项目之后可以单独将所需要的头文件和库文件(.lib、.dll)拷贝到我们的项目中,然后修改附加包含目录为我们的新目录就可以了。这有点类似上面两种方法的组合使用,但是我觉得更像是将其作为第三方库使用,比如我对BCG或者AddFlow就是这样用的。
二、简单解析HelloWorld
这对于了解游戏开发是有帮助的。
1、游戏的运行
打开HelloWorld项目(官方Demo)的AppDelegate.cpp文件,查看applicationDidFinishLaunching函数,
bool AppDelegate::applicationDidFinishLaunching() { // initialize director CCDirector *pDirector = CCDirector::sharedDirector(); pDirector->setOpenGLView(CCEGLView::sharedOpenGLView()); // turn on display FPS pDirector->setDisplayStats(true); // set FPS. the default value is 1.0/60 if you don't call this pDirector->setAnimationInterval(1.0 / 60); // create a scene. it's an autorelease object CCScene *pScene = HelloWorld::scene(); // run pDirector->runWithScene(pScene); return true; }
(1)pDirector->setDisplayStats(true):设置是否显示游戏帧数等调试信息。
(2)pDirector->setAnimationInterval(1.0 / 60):设置游戏的帧率,即60帧每秒。
(3)CCScene *pScene = HelloWorld::scene():创建一个场景。
(4)pDirector->runWithScene(pScene):利用上面创建的场景运行游戏。
帧是游戏开发里很重要的概念。之所以能够看到游戏在不断地运动,是因为很多静止的画面快速连续切换产生了错觉。程序用线程不断地切换画面,每个画面就是一帧,帧率就是每秒程序切换的帧数。
2、场景类HelloWorld
先看场景类的头文件代码,
class HelloWorld : public cocos2d::CCLayer { public: // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); // implement the "static node()" method manually CREATE_FUNC(HelloWorld); };
其中init函数是初始化函数;scene是一个静态函数,用于获取场景对象;menuCloseCallback是一个响应菜单按钮的回调函数;CREATE_FUNC(HelloWorld)是一个宏函数,它实现了HelloWorld的create函数,其定义如下:
/** * define a create function for a specific type, such as CCLayer * @__TYPE__ class type to add create(), such as CCLayer */ #define CREATE_FUNC(__TYPE__) \ static __TYPE__* create() \ { \ __TYPE__ *pRet = new __TYPE__(); \ if (pRet && pRet->init()) \ { \ pRet->autorelease(); \ return pRet; \ } \ else \ { \ delete pRet; \ pRet = NULL; \ return NULL; \ } \ }
CCScene* HelloWorld::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; }
其中,CCScene *scene = CCScene::create():创建一个场景对象;
HelloWorld *layer = HelloWorld::create():创建HelloWorld自身的对象,它是利用CREATE_FUNC(Hello2创建的,但HelloWorld本身并不是一个CCScene场景类,而是一个CCLayer类;
scene->addChild(layer):将layer添加到scene对象;
return scene:返回场景对象。
最后,梳理一遍场景类对象的创建过程,即:
(1)通过CCScene *pScene = HelloWorld::scene()创建一个场景对象。
(2)HelloWorld的scene函数里创建了一个CCScene对象,然后将HelloWorld对象添加到场景中。
(3)HelloWorld对象通过create函数创建,而create函数是由宏CREATE_FUNC(HelloWorld)定义的。
(4)通过pDirector->runWithScene(pScene)让场景对象显示在窗口中。
三、重新创建场景类
在新创建的工程中添加MyHelloWorldScene.h和MyHelloWoldScene.cpp两个文件,其代码如下:
MyHelloWorldScene.h
#ifndef __MY_HELLOWORLD_SCENE_H__ #define __MY_HELLOWORLD_SCENE_H__ #include "cocos2d.h" using namespace cocos2d; class MyHelloWorldScene : public CCLayer { public: /* 通过静态的scene函数,创建一个场景对象 */ static CCScene* scene(); /* MyHelloWorldScene的初始化工作都在init里执行 */ virtual bool init(); /* 调用CREATE_FUNC定义create函数 */ CREATE_FUNC(MyHelloWorldScene); }; #endif // __MY_HELLOWORLD_SCENE_H__
MyHelloWoldScene.cpp
#include "MyHelloWorldScene.h" CCScene* MyHelloWorldScene::scene() { // 创建一个场景对象 CCScene* scene = CCScene::create(); // 创建MyHelloWorldScene对象 MyHelloWorldScene* layer = MyHelloWorldScene::create(); // 添加MyHelloWorldScene到场景中 scene->addChild(layer); return scene; } bool MyHelloWorldScene::init() { //创建一个精灵并且添加到场景中 CCSprite* sprite = CCSprite::create("CloseNormal.png"); sprite->setPosition(ccp(200, 200)); this->addChild(sprite); return true; }