首页 > 代码库 > cocos2d-x 3.0 绘图节点——Node

cocos2d-x 3.0 绘图节点——Node

***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************



昨天写了个场景切换,折腾到半夜。。好困的说。。。


***************************

照旧,先来个目录:

1.前言

2.从代码观节点

3.实际应用Node类

***************************




1.前言

老样子,先来点干货

要说Node,当然,先上大菜——API



节点解释:节点是场景图的基本元素。场景图的基本元素必须是节点对象或者是节点对象的子类。

其中主要可以看到Layer、MenuItem、Scene、Sprite、TMXTiledMap(解析and渲染TMX地图)、ParticleSystem(粒子系统基类)等等

Node是这些类的根类

其中要注意,Node的这些子类都可以互相嵌套,Because:

一个节点的主要特点如下:

  • 他们可以包含其他的节点对象(addChildgetChildByTagremoveChild, etc)
  • 他们可以安排定期的回调(scheduleunschedule, etc)
  • 他们可以执行一些动作(runActionstopAction, etc)

第一条就说了,它可以包含其他节点的对象,所以,节点的子类都是可以互相嵌套的。

我们也可以发现,很多类继承图中都可以看到Ref,

Ref何许人也,这么强大?

Ref类,其实是3.0变动过来的类名,原来叫做CCObject,它实现了一套内存管理的机制,因此,cocos2d-x中所有类都是Ref的子类。





2.从代码观节点


具体在代码上,我们可以在程序里看,

进入到Scene的定义,可以看到:

<span style="font-family:Times New Roman;font-size:12px;">class CC_DLL Scene : public Node
{
public:
    /** creates a new Scene object */
    static Scene *create();

    // Overrides
    virtual Scene *getScene() override;

    using Node::addChild;
    virtual std::string getDescription() const override;
    
CC_CONSTRUCTOR_ACCESS:
    Scene();
    virtual ~Scene();
    
    virtual bool init() override;

protected:
    friend class Node;
    friend class ProtectedNode;
    friend class SpriteBatchNode;
    
private:
    CC_DISALLOW_COPY_AND_ASSIGN(Scene);
    
#if CC_USE_PHYSICS
public:
    virtual void addChild(Node* child, int zOrder, int tag) override;
    virtual void update(float delta) override;
    inline PhysicsWorld* getPhysicsWorld() { return _physicsWorld; }
    static Scene *createWithPhysics();
    
CC_CONSTRUCTOR_ACCESS:
    bool initWithPhysics();
    
protected:
    void addChildToPhysicsWorld(Node* child);

    PhysicsWorld* _physicsWorld;
#endif // CC_USE_PHYSICS
};</span>

首先,Scene是继承自Node的,所以场景也是一个节点,而场景比节点多了一个锚点。也可以看到里面有addChild、update、物理引擎,而且也有3.0最新增加的addChildToPhysicsWorld。

所以Scene是所有场景的根节点,是所有节点数的根节点,因此,我们绘图的时候,要先创建一个场景,然后再往场景里面加一些其他的东西。以HelloWorldScene为例:

HelloWorldScene里面包含了

——Sprite(背景图片)

——Menu(菜单项)

——LabelTTF(文本层)


恩,接下来瞅瞅Layer,转到Layer的定义:

<span style="font-size:18px;font-family: Arial;"> </span><span style="font-family:Times New Roman;font-size:10px;">// Deprecated touch callbacks.
    CC_DEPRECATED_ATTRIBUTE virtual bool ccTouchBegan(Touch *pTouch, Event *pEvent) final {CC_UNUSED_PARAM(pTouch); CC_UNUSED_PARAM(pEvent); return false;};
    CC_DEPRECATED_ATTRIBUTE virtual void ccTouchMoved(Touch *pTouch, Event *pEvent) final {CC_UNUSED_PARAM(pTouch); CC_UNUSED_PARAM(pEvent);}
    CC_DEPRECATED_ATTRIBUTE virtual void ccTouchEnded(Touch *pTouch, Event *pEvent) final {CC_UNUSED_PARAM(pTouch); CC_UNUSED_PARAM(pEvent);}
    CC_DEPRECATED_ATTRIBUTE virtual void ccTouchCancelled(Touch *pTouch, Event *pEvent) final {CC_UNUSED_PARAM(pTouch); CC_UNUSED_PARAM(pEvent);}
    
    CC_DEPRECATED_ATTRIBUTE virtual void ccTouchesBegan(__Set *pTouches, Event *pEvent) final {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
    CC_DEPRECATED_ATTRIBUTE virtual void ccTouchesMoved(__Set *pTouches, Event *pEvent) final {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
    CC_DEPRECATED_ATTRIBUTE virtual void ccTouchesEnded(__Set *pTouches, Event *pEvent) final {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
    CC_DEPRECATED_ATTRIBUTE virtual void ccTouchesCancelled(__Set *pTouches, Event *pEvent) final {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}</span>

先看这几行,就可以发现,Layer比Node多了一些用户的交互,比如:用户的触摸(点击、滑动)消息和重力感应。


由以上两点,可以发现Node是一个很重要的类。

转到Node的定义可以看到,它包含

——create 不用说了

——getDescription获取描述

——setLocalZOrder(_setLocalZOrder)    设置Z轴,就是一个场景可能有多个图层,安排他们上下关系。

——setScale 缩放显示,后面有X就是缩放X轴,如果什么都没有就是整体缩放,参数浮点类型

——setPosition设置坐标

——setSkew设定扭曲,用法同Scale

——setAnchorPoint设定锚点,就是一幅画的图钉

——setVisible节点是否可见,并不是不在内存中,而是需不需要绘制出来

——setRotation节点的旋转

——addChild添加子节点

——getChildByTag根据标记获取节点

——setParent设定节点的父节点

——removeChild移除节点

——setUsersData让节点绑定数据

——onEnter(onExit、resume、pause)节点的生命周期方法

——cleanup让节点所有动作停止

——visit通过递归遍历所有的节点

——runAction节点绑定一个动作

——update节点的更新方法

——convertToWorldSpace坐标系变换为世界坐标系

等等。。。好多好多。。。好累

上述有很多是一系列的,只举了一个例子,比如:

set表示设置,get表示获取

....X表示  对X轴操作,....Y  对Y轴操作,....Z  对Z轴操作。


综上所述吧,Node类包含的属性主要包括:

————绘图and变换  属性

  • 位置(默认值:x=0,y=0)
  • 缩放(默认值:x=1,y=1)
  • 旋转(以角度为单位,按顺时针方向)(默认值:0)
  • 锚点(默认值:x=0,y=0)
  • 内容大小(默认值:width=0,heigh=0)
  • 可见性(默认值:true)

————子节点child(添加,移除,获取)

————运行动作(Action,ActionManager)

————生命周期(onEnter、onExit、resume、pause)

————节点数据(tag节点的标记,userData绑定数据)

————计划任务 Schedule

是不是清晰了很多呢?





3.实际应用Node类

说了这么多,嘴都干了,来点实际应用吧


①我们来耍耍这些个位置,锚点

先新建一个项目,运行:


然后,我们改变一下,背景图层(sprite)的setposition为(0,0):

 // add "HelloWorld" splash screen"
    auto sprite = Sprite::create("HelloWorld.png");

    // position the sprite on the center of the screen
    sprite->setPosition(0,0);

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

这样,再次运行:



发现,图片到了左下角,为什么呢?

这就是锚点,之前我说过,锚点就相当于,一颗钉子,默认是在图片中央的。

所以,我们将场景放置在0,0,即将锚点对准坐标0,0。

所以,图片会在左下角,还记得原来是什么样子的吗?

sprite->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
visibleSize是之前获取的屏幕大小:

Size visibleSize = Director::getInstance()->getVisibleSize();


原来坐标是放置在哪里呢?就是在屏幕中间,那什么是origin.x和origin.y?

Point origin = Director::getInstance()->getVisibleOrigin();
这个是用来获取可视化区域的起点坐标,目的就是适配,让在不同分辨率下都能在同一个相对位置。


那我们来调整一下锚点,是不是就不一样了呢?

将锚点设置为(0,0):

sprite->setAnchorPoint(Point(0,0));
运行一下:



图片的锚点在左下角,而放置位置是在屏幕中心,所以,位置关系是这个样子的。


②接下来,来试一试Node的动作属性

就来一个简单的动作吧,移动~

新建一个动作:

auto act=MoveTo::create(2,Point(0,0));
第一个参数是执行这个动作花费的时间,第二个参数,就是移动到哪个位置。

然后,让sprite执行这个动作:

sprite->runAction(act);
然后,运行一下~


当然,不止sprite可以,你的HelloWorld字也可以执行,只要是Node的子类就能执行这个动作,

不信,不信你试试呀~

auto act=MoveTo::create(2,Point(0,0));
label->runAction(act);

OK,就是酱紫啦~


过两天就要出国一趟,去韩国旅旅游,要走10天,可能就不更新了


***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************