对应第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);
其中,setFrameSize函数是用来设置游戏窗口大小的,参数可以自行修改;setFrameZoomFactor可以让窗口进行缩放,但是它只针对计算机,对手机是无效的。下面利用VS向导创建一个Cocos2d-x游戏项目。
一、解决编译报错的方案
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; \
} \
}
然后重点看看源文件HelloWorld.cpp中scene的实现函数:
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;
}
打开AppDelegate.cpp文件,找到applicationDidFinishLaunching函数,把CCScene *pScene = HelloWorld::scene()修改为CCScene *pScene = MyHelloWorld::scene(),然后运行项目,就可以看到新的场景了:只有一个关闭按钮的游戏界面。