本篇所用的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…等等的,当你对他们再熟悉不过的时候,它们就是你的搭建游戏世界的基础,为你的游戏提供无限的精彩,好了第一篇就暂时写到这了,我们下一期见吧!