我从一开始接触的Cocos2d-x 1.04到现在Cocos2d-x 3.3Final我都没有能很细致的去分析其核心底层,所以初学的同学,我建议先别去触碰那块,会让你晕很久,所以就由简入深的慢慢去学吧,那么我就简单的讲讲我所熟悉的Cocos2d-x HelloWorld。本篇所用的Cocos2d-x版本为:Cocos2d-x 3.2

当我们配置好Cocos2d-x相关的部署后,我们一般都会创立第一个测试项目,那么我们第一所见是什么?HelloWorld!是的,在我学习的时候也是一样的,那么我们看看HelloWorld带给我们的是什么呢?

HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include “cocos2d.h”

class HelloWorld : public cocos2d::Layer
{
public:
// 静态创建一个Scene类
static cocos2d::Scene* createScene();

// 重载基类Layer的init函数
virtual bool init();

//按钮关闭回调函数
void menuCloseCallback(cocos2d::Ref* pSender);

// 手动实施,静态创建HelloWorld方法:
CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__

HelloWorldScene.cpp

Scene* HelloWorld::createScene()
{
// scene 场景 是一个自动释放对象
auto scene = Scene::create();

// layer 图层 是一个自动释放对象
auto layer = HelloWorld::create();

// scene场景 添加一个layer图层;
// scene是layer的父级
//layer是scene的孩子
scene->addChild(layer);

// 返回场景
return scene;
}

// on “init” you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. 基类Layer初始化
if ( !Layer::init() )
{
//初始化失败
return false;
}
// 通过单例导演类获取OpenGL 视图的可见大小
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
// 通过单例导演雷获取OpenGL视图的初始化时的可见大小
// 创建一个图像菜单按钮
// 1. Normal 状态,图片路径 2. Selected 状态 图片路径 3. 按钮回调事件
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));

// 创建一个菜单, 将图像菜单按钮加入到Menu
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Vec2::ZERO);
// 本类指针添加menu为孩子,显示层级为1
this->addChild(menu, 1);

/////////////////////////////
// 3. 创建一个文本框

// 1. 文本字符串 2. 文本字体, 3. 字体大小
// create and initialize a label

auto label = Label::createWithTTF(“Hello World”, “fonts/Marker Felt.ttf”, 24);

// position the label on the center of the screen
label->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y + visibleSize.height – label->getContentSize().height));

// add the label as a child to this layer
this->addChild(label, 1);

// 创建一个精灵
auto sprite = Sprite::create(“HelloWorld.png”);

// position the sprite on the center of the screen
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

// add the sprite as a child to this layer
this->addChild(sprite, 0);

return true;
}

void HelloWorld::menuCloseCallback(Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
MessageBox(“You pressed the close button. Windows Store Apps do not implement a close button.”,”Alert”);
return;
#endif

Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}

总体上来讲,通过HelloWorld我们遇到了7个小伙伴:Scene、Layer、Menu、Sprite、LabelTTF、MenuItemImage、Ref。那么我就来说说在我眼里这些小伙伴都是干嘛的。

先来说说他们可不告人的关系(嘿嘿嘿…)

Scene

我理解为就是地球,Layer呢就是地球上一个个的大陆或者海洋、国家之类的可以区分的,当然了苍井空是世界的(嘿嘿嘿…),Menu、Sprite、LabelTTF、MenuItemImage、Ref这些等等都是地球上的生物或者建筑。

如果说Scene是宇宙的话,那么Layer就是一颗颗星球,Menu、Sprite、LabelTTF、MenuItemImage、Ref等等都是这个星球的组成部分。这么说的话,我想大家都能有一些概念了,那么接下来,Scene到底是什么?

粗浅的讲Scene就是一个场景,深入点讲Scene是渲染树(以后会有详细的介绍)。

我们所做的Cocos2d项目,只能有一个主场景,哪怕你场景再多,也只能在当前场景上做事情,否则必须要切换当前场景。(NotificationNode以后再说),那么也就是说,我们的游戏只能允许一个场景在导演类上跑。也就是这点导致我在初学的时候养成了把Scene当成主管理器来使用的习惯,手动实现切换不同Layer达到我想要的界面效果。官方给我们demo基本都是执行的切换场景操作,但是因为上述所说养成了习惯就不好改了,这块大家根据自己的理解运用就行了,但是还是要根据不同的项目,不同的经历来决定的。

在我的理解上,官方提供的demo上的Scene可以这样玩。创建一个Scene来添加不同的Layer进行或者可以根据不同的Scene创建不同的Layer(好像是废话哈),就好比HelloWorld来说我们可以看见

// layer 图层 是一个自动释放对象
auto layer = HelloWorld::create();

当前HelloWorld既是个场景同时也是个图层。

为什么说是场景,因为HelloWorld类实现了静态单例创建场景接口,以供Director导演类加载。

详细代码我们可以通过AppDelegate.cpp文件内查找到

bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLViewImpl::create(“My Game”);
director->setOpenGLView(glview);
}

// turn on display FPS
director->setDisplayStats(true);

// set FPS. the default value is 1.0/60 if you don’t call this
director->setAnimationInterval(1.0 / 60);

// create a scene. it’s an autorelease object
// 这这这,请看这里
auto scene = HelloWorld::createScene();

// // 这这这,请看这里
director->runWithScene(scene);

return true;
}

为什么说是图层,因为HelloWorld本身是继承Layer的

只不过因为实现了 静态单例创建场景的方法 使得我们的HelloWorld可以作为场景使用

class HelloWorld : public cocos2d::Layer // 这这请看这里
{

}

在createScene方法中我们看到
// layer 图层 是一个自动释放对象
auto layer = HelloWorld::create();
我们的这个场景里面加载了HelloWorld图层。

那么举一反三,是不是我们也可以单独创建一个场景来作为管理器,通过添加不同的Layer类来实现呢?于是乎我就养成了把Scene当初管理器的习惯。

好了Scene简单的说完了,再来说说Layer

什么是Layer?

Layer刚才我们已经通过文字描述粗浅的意识到是什么了,就像上述所说,Scene是太阳系的话,Layer就是地球,我们就是生活在地球上的Sprite精灵等,我们已经拥有了太阳系(Scene)是不是必须要有地球、太阳之类的Layer才能存活呢。那么Layer就是承载着Menu、Sprite、LabelTTF等这些小伙伴必不可少的土壤,也因为承载着这么多的小伙伴,所以Layer才更会有价值。

什么是Sprite等?

Sprite就是Cocos2d-x提供给我们最为基础的几个元素中的一个,它就好比是生活在地球上的人类、动画、植物、建筑等等的东西。

在学习Cocos2d-x的时候,我建议同学们先从最基础的开始了解,就好比说Sprite,它有多少种创建方式,每种创建方式所带来的效果是什么,可以给我们带来哪些启发,然后一点点的继续Menu、Layer、Scene…等等的,当你对他们再熟悉不过的时候,它们就是你的搭建游戏世界的基础,为你的游戏提供无限的精彩,好了第一篇就暂时写到这了,我们下一期见吧!