在 cocos2d-x 开头配置(Windows 平台)中,介绍了新建工程,这篇就介绍下 cocos2d-x 的一些概念。(前提是需要有C++的面向对象的基本知识和C++11的常用知识)
层,场景,导演,精灵,菜单
打开新建的工程(不管是VS,XCODE, Eclipse对 cocos2d-x 都一样),在 Classes 下找到
AppDelegate.h AppDelegate.cpp HelloWorldScene.h HelloWorldScene.cpp
暂时先不管 AppDelegate.h AppDelegate.cpp 这两个,先看看 HelloWorldScene.h 这个文件
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ // 引入 cocos2d-x #include "cocos2d.h" class HelloWorld : public cocos2d::Layer { public: // 创建场景的静态函数 static cocos2d::Scene* createScene(); // 初始化 virtual bool init(); // 菜单回调函数 void menuCloseCallback(cocos2d::Ref* pSender); // 添加默认的静态创建函数 CREATE_FUNC(HelloWorld); }; #endif // __HELLOWORLD_SCENE_H__
没几行,就是定义了一个 HelloWorld 的类,继承 Layer ,而 Layer 就是 层,同样 HelloWorld 也是 层;HelloWorld 还声明四个函数(最后一个也是,后面说)。
接着看 CPP 文件前几行
#include "HelloWorldScene.h" USING_NS_CC; Scene* HelloWorld::createScene() { // 创建场景 auto scene = Scene::create(); // 创建层 新建 HelloWorld 对象 auto layer = HelloWorld::create(); // 添加层 scene->addChild(layer); // return the scene return scene; }
USING_NS_CC; 使用 cocos2d-x 的命名空间,这样就不用像头文件 cocos2d::Layer 那样
scene->addChild(layer); 向场景中添加子节点
cocos2d-x 采用了类似 OC 的内存管理机制,导演,场景,层,精灵,菜单 都继承自 节点 Node 都有这个函数,还有很多其他函数。
HelloWorld::create(); 是头文件中 CREATE_FUNC(HelloWorld); 宏添加的静态函数,自动调用 init();
所以不定义 bool init(); 会编译出错。
create(); 函数是 cocos2d-x 中一个十分重要的函数 cocos2d-x 的大部分类都使用它或者衍生形式来创建对象,不能使用 new Layer();这种方式,这么做是为了引擎的内存管理能正确的工作。
接着看 初始化 函数
bool HelloWorld::init() { // 1. super init first // 先调用父类的 if ( !Layer::init() ) { return false; } // 导演第一次出现 获取屏幕大小 Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); // 2. add a menu item with "X" image, which is clicked to quit the program // you may modify it. // 添加个按钮 auto closeItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 , origin.y + closeItem->getContentSize().height/2)); // 添加菜单 auto menu = Menu::create(closeItem, NULL); menu->setPosition(Vec2::ZERO); this->addChild(menu, 1); // 3. add your codes below... // 添加标题,使用字体 auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24); // 设置位置 label->setPosition(Vec2(origin.x + visibleSize.width/2, origin.y + visibleSize.height - label->getContentSize().height)); this->addChild(label, 1); //添加精灵 auto sprite = Sprite::create("HelloWorld.png"); sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); this->addChild(sprite, 0); return true; }
这里第一次出现导演,导演是单例, 使用
Director::getInstance();
获得惟一的对像,可以在程序任意位置使用,十分方便,导演控制着场景转换,管理游戏的开始,暂停,获取必要的系统信息,功能强大。
AppDelegate.cpp 中应用初始化完成的最后一步就是跑游戏的第一个场景
// run
director->runWithScene(scene);
下面添加按钮,菜单
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
auto menu = Menu::create(closeItem, NULL);
按钮的 create 三个参数分别是正常显示的图片,按钮按下时的图上,按下按钮的回调函数:
void HelloWorld::menuCloseCallback(Ref* pSender) //回调函数的参数类型固定,定义时注意匹配 { // 结束游戏 Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif }
菜单的 create 的参数是可变的,可以添加多个按钮,要以 NULL(推荐使用 nullptr)结束。
cocos2d-x 的在线API可以找到这些函数原型,cocos2d-x 的命名清晰,大部分情况下可以做到见名知意,也可以利用编译器进入到引擎内部看源码,多看这些API和源码可以加快理解引擎的机制。
添加个标题,标题是文字, Lable 是引擎中显示文字的类,这里用到的是 create 的衍生版本
auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
三个参数分别是 显示的内容,字体和字号
auto sprite = Sprite::create("HelloWorld.png");
创建精灵,创建精灵的参数很简单就是张图片。
精灵和上面的一样都有几个创建的函数,一种是函数重载,有几个参数不同的同名函数,别一种是带有 With.. 的衍生版本
精灵最大的特点在于它可以执行多种多样的动作(后面再说)
把游戏比做精彩的戏剧,精灵无疑是出场最多的演员可谓是当之无愧的主角,字体,菜单按钮时常出来跑个龙套,层则剧场中不可或缺的布景,道具,场景就是在这之下的根基,导演则在一边指挥演出。