Cocos2dX的基础知识

坐标系

1. OpenGL坐标系

  1. Cocos2d-xOpenGLOpenGL ES为基础,该坐标系原点在屏幕左下角,x轴向右,y轴向上。

2. 屏幕坐标系

屏幕坐标系使用的是不同的坐标系统,原点在屏幕左上角,x轴向右,y轴  向下。

3. Cocos2d-x中的父子关系的层级结构

在cocos中,每个元素跟元素间是层级关系,每个元素称为“节点",当一个节点成为另一个的子节点时,该子节点的坐标系就成为了相对坐标系,x轴参数跟y轴参数此时相对于父节点的原点开始计算。

屏幕分辨率获得

getWinSize(); //获取设备屏幕大小.
getVisibleSize(); //获得视口(可视区域)的大小。
getVisibleOrigin(); //获得可视区域的出发点坐标,在处理相对位置时,确保节点在不同分辨率下的位置一致。
//例如:
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();

//屏幕坐标如何转化为GL坐标
auto GL_Position = Director::getInstance()->converToGL(Mouse->getPosition());

Cocos中节点的关系

  1. 导演(Director) 管理场景
  2. 场景(Scene) 可见画面
  3. 层(Layer) 容纳节点
  4. 精灵(Sprite) 组成元素 “演员”

关系:

(1)导演->(N)场景->(N)层->(N)精灵

相关代码例如:

auto director = Director::getInstance();    //获得一个导演的实例
auto scene = HelloWorld::createScene();        //生成一个HelloWorld场景
this->addChild(sprite, 0);        //将sprite精灵挂载到第0层上
auto sprite = Sprite::create("sprite.png");    //生成一个精灵

1. 导演(Director)

Cocos2d-x 使用导演的概念,这个导演和电影制作过程中的导演一样!导演控制电影制作流程,指导团队完成各项任务。在使用 Cocos2d-x 开发游戏的过程中,你可以认为自己是执行制片人,告诉 导演(Director) 该怎么办!一个常见的 Director 任务是控制场景替换和转换。 Director是一个共享的单例对象,可以在代码中的任何地方调用。

这是一个典型的游戏流程实例。当您的游戏设计好时,Director 就负责场景的转换:

一. Cocos2dX的基础知识 - 图1

你是你的游戏的导演。你决定着发生什么,何时发生,如何发生。

2. 场景(Scene)

现在我们知道,场景是用来挂载节点(Node)的,它把场景内所有的 节点(Node) 都包含在一个 树(tree)

一. Cocos2dX的基础知识 - 图2

当你开发游戏的时候,你会添加一些节点,精灵和动画到一个场景中,你期望的是每一个添加的对象都能被正确的展示,可是如果有个对象没有被展示呢?可能你错误的把这个对象隐藏到背景中了。怎么办?别着急,这是个小问题,停下来,拿出一张纸,把场景图画出来,你肯定能很容易的发现错误。

既然场景图是一个树结构,你就能遍历它,Cocos2d-x 使用 中序遍历,先遍历左子树,然后根节点,最后是右子树。中序遍历下图的节点,能得到 A, B, C, D, E, F, G, H, I 这样的序列。

一. Cocos2dX的基础知识 - 图3

比如经典的游戏超级玛丽,也可以用节点的思想来拆分游戏场景

image.png

3. 精灵(Sprite)

所有的游戏都有 精灵(Sprite) 对象,或类似概念,精灵是您在屏幕上移动的对象,它能被控制。你喜欢玩的游戏中主角可能就是一个精灵,我知道你在想是不是每个图形对象都是一个精灵,不是的,为什么? 如果你能控制它,它才是一个精灵,如果无法控制,那就只是一个节点(Node)。比如说文本(Label) 节点等。

让我们来简单创建一个精灵

auto mySprite = Sprite::create("mysprite.png");    //这是一个创建语句,注意,现在只是创建了一个精灵,但还没有挂载到我们游戏的场景层上,所以并不能显示
mySprite->setPosition( Vec2(500,0) );    //设置精灵位置
mySprite->setRotation(40);    //设置旋转度数
mySprite->setScale(2.0); //设置缩放,如果只有一个参数则等比例缩放,两个参数则x,y缩放比例不同
mySprite->setAnchorPoint(Vec2(0, 0)); //设置锚点(即精灵的中心原点位置,默认0,0)
//添加到层中
This->addChild(mySprite,0); //this表示当前场景,添加进第0层中

4. 动作(Action)

怎么让精灵动起来。动作(Action) 就是用来解决这个问题的,它可以让精灵在场景中移动,如从一个点移动到另外一个点。你还可以创建一个动作 序列(Sequence) ,让精灵按照这个序列做连续的动作,在动作过程中你可以改变精灵的位置,旋转角度,缩放比例等等。

Action 对象的创建:

auto mySprite = Sprite::create("Blue_Front1.png");

// 创建一个移动对象,2秒内向右移动50像素,并向上移动10像素
auto moveBy = MoveBy::create(2, Vec2(50,10));
// 让该移动对象moveBy在我们的精灵上运行
mySprite->runAction(moveBy);

// 而MoveTo的用法与MoveBy相似,唯一区别是,MoveTo的目标坐标为屏幕上从左下角开始的绝对坐标,而MoveBy是相对于精灵原先的位置做偏移
auto moveTo = MoveTo::create(2, Vec2(50,10));
mySprite->runAction(moveTo);

5. 序列(Sequence)

如果一次运动要同时执行多个动作(Action) ,Cocos2d-x 通过 序列(Sequence) 来支持这种需求。

顾名思义,序列就是多个动作按照特定顺序的一个排列,当然反向执行这个序列也是可以的,Cocos2d-x 能很方便的完成这项工作。

让我们来看一个通过序列控制精灵移动的例子:

一. Cocos2dX的基础知识 - 图5

创建 Sequence

auto mySprite = Node::create();

// 第一个动作,2s内移动至绝对坐标(50,10)
auto moveTo1 = MoveTo::create(2, Vec2(50,10));

// 第二个动作,2s内在目前位置上向右上偏移(100,10)
auto moveBy1 = MoveBy::create(2, Vec2(100,10));

// 第三个动作,2s内移动至绝对坐标(150,10)
auto moveTo2 = MoveTo::create(2, Vec2(150,10));

// 创建延时delay对象
auto delay = DelayTime::create(1);
// 在用户精灵上运行一个序列(Sepuence)
mySprite->runAction(Sequence::create(moveTo1, delay, moveBy1, delay.clone(),
moveTo2, nullptr));

但是如果想要所有的动作同时一起执行

Cocos2d-x 也支持!通过引擎中的 Spawn 对象,你能让多个动作同时被解析执行。但可能不同动作的执行时间不一致,在这种情况下,他们不会同时结束。

auto myNode = Node::create();

auto moveTo1 = MoveTo::create(2, Vec2(50,10));
auto moveBy1 = MoveBy::create(2, Vec2(100,10));
auto moveTo2 = MoveTo::create(2, Vec2(150,10));

myNode->runAction(Spawn::create(moveTo1, moveBy1, moveTo2, nullptr));

6. 日志输出

有时,在你的游戏正在运行的时候,为了了解程序的运行过程或是为了查找一个 BUG,你想看到一些运行时信息,可以! 这个需求引擎已经考虑到了,使用 log() 可以把信息输出到控制台,这样使用:

// 输出一个字符串
log("正在创建");

// 组合输出
string s = "My variable";
log("当前字符串为: %s", s);

// 输出具体数据
double kk = 42;
log("double is %f", kk);
int i = 6;
log("integer is %d", i);
float f = 2.0f;
log("float is %f", f);

// 输出详细情况
bool b = true;
if (b == true)
    log("当前创建正确");
else
    log("创建失败");


7. 修改工程参数

默认的cocos项目,会自动在窗口的左下角增加系统相关参数的显示,可在
image.pngimage.png
AppDelegate.cpp 中修改为director->setDisplayStats(false);即可

更改工程窗口分辨率,可以修改AppDelegate.cpp文件的这部分参数

...
USING_NS_CC;

static cocos2d::Size designResolutionSize = cocos2d::Size(1024, 768); //默认分辨率在这修改
static cocos2d::Size smallResolutionSize = cocos2d::Size(480, 320);
static cocos2d::Size mediumResolutionSize = cocos2d::Size(1024, 768);
static cocos2d::Size largeResolutionSize = cocos2d::Size(2048, 1536);

AppDelegate::AppDelegate()
{
}
...

修改默认场景,可以修改AppDelegate.cpp文件的这部分代码

... 

register_all_packages();

// create a scene. it's an autorelease object
auto scene = HelloWorld::createScene();    //此代码控制开启后第一个调用的场景,默认为HelloWorld

// run
director->runWithScene(scene);

return true;

...