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