Cocos2dx引擎笔记——渲染和动画

Cocos2d-x坐标系和OpenGL坐标系相同,都是起源于笛卡尔坐标系。

笛卡尔坐标系

笛卡尔坐标系中定义右手系原点在左下角,x向右,y向上,z向外,OpenGL坐标系为笛卡尔右手系。

屏幕坐标系和Cocos2d坐标系

iOS,Android,Windows Phone等在开发应用时使用的是标准屏幕坐标系原点为屏幕左上角,x向右,y向下。

Cocos2d坐标系和OpenGL坐标系一样,原点为屏幕左下角,x向右,y向上


世界坐标系(World Coordinate) VS 本地坐标系(Node Local)

世界坐标系也叫做绝对坐标系,是游戏开发中建立的概念。因此,“世界”指游戏世界。

本地坐标系也叫相对坐标系,是和节点相关联的坐标系。每个节点都有独立的坐标系,当节点移动或改变方向时,和该节点关联的坐标系将随之移动或改变方向。通过Node的setPosition设定元素的位置使用的是相对与其父节点的本地坐标系。最后在绘制屏幕的时候cocos2d会把这些元素的本地坐标映射成世界坐标系坐标

锚点(Anchor Point)

将一个节点添加到父节点里面时,需要设置其在父节点上的位置,本质上是设置节点的锚点在父节点坐标系上的位置。

  • Anchor Point的两个参数都在0~1之间。它们表示的并不是像素点,而是乘数因子。(0.5,0.5)表示Anchor Point位于节点长度乘0.5和宽度乘0.5的地方,即节点的中心。

  • 在Cocos2d-x中Layer的Anchor Point为默认值(0,0),其他Node的默认值为(0.5,0.5)。

我们用以下代码为例,使用默认Anchor Point值,将红色层放在屏幕左下角,绿色层添加到红色层上:

auto red = LayerColor::create(Color4B(255,100,128),visibleSize.width/2,visibleSize.height/2);

auto green = LayerColor::create(Color4B(100,255,visibleSize.width/4,visibleSize.height/4);

red->addChild(green);

this->addChild(red,0);

我们用以下代码为例,将红色层的Anchor Point设为中点放在屏幕中央,绿色层添加到红色层上,绿色层锚点为右上角:

注:因为Layer比较特殊,它默认忽略锚点,所以要调用ignoreAnchorPointForPosition()接口来改变锚点,关于ignoreAnchorPointForPosition()接口的使用说明,我们将在后面详细讲解。

 

忽略锚点(Ignore Anchor Point)

Ignore Anchor Point全称是ignoreAnchorPointForPosition,作用是将锚点固定在一个地方。

如果设置其值为true,则图片资源的Anchor Pont固定为左下角,否则即为所设置的位置。

我们用以下代码为例,将两个层的ignoreAnchorPointForPosition设为true,并将绿色的层添加到红色的层上:

auto red = LayerColor::create(Color4B(255,visibleSize.height/2); red->ignoreAnchorPointForPosition(true); red->setPosition(Point(visibleSize.width/2 + origin.x,visibleSize.height/2 + origin.y)); auto green = LayerColor::create(Color4B(100,visibleSize.height/4); green->ignoreAnchorPointForPosition(true); red->addChild(green); this->addChild(red,0);

VertexZ,PositionZ和zOrder

  • VerextZ是OpenGL坐标系中的Z值
  • PositionZ是Cocos2d-x坐标系中Z值,越大层次越在上。
  • zOrder是Cocos2d-x本地坐标系中Z值

实际开发中我们只需关注zOrder。可以通过setPositionZ接口来设置PositionZ。以下是setPositionZ接口的说明:

Sets the 'z' coordinate in the position. It is the OpenGL Z vertex value.

即PositionZ的值即为opengl的z值VertexZ。同样节点的PositionZ也是决定了该节点的渲染顺序,值越大,但是与zOrder不同的区别在于,PositionZ是全局渲染顺序即在根节点上的渲染顺序,而zOrder则是局部渲染顺序,即该节点在其父节点上的渲染顺序,与Node的层级有关。用以下事例来说明:

 虽然green的zOrder大于red的zOder,但是因为red的PositionZ较大,所以red还是在green上面显示。

触摸点(Touch position)

所以在处理触摸事件时需要用重写以下四个函数:

virtual bool onTouchBegan(Touch *touch,Event * event);
    virtual void onTouchEnded(Touch *touch,Event * event);
    virtual void onTouchCancelled(Touch *touch,Event * event);
    virtual void onTouchMoved(Touch *touch,Event * event);

游戏逻辑时需要用到触摸点在Cocos2d坐标系中的位置,就需要将touch的坐标转换成OpenGL坐标系中的点坐标。

Touch position是屏幕坐标系中的点OpenGL position是OpenGL坐标系上的点坐标。通常我们在开发中会使用两个接口getLocation()getLocationInView()来进行相应坐标转换工作。

getLocation()获取触摸点的GL坐标,而getLocation()内部实现是通过调用Director::getInstance()->convertToGL(_point);返回GL坐标。

世界坐标系和本地坐标系的相互转换方法:

// 把世界坐标转换到当前节点的本地坐标系中
    Point convertToNodeSpace(const Point& worldPoint) const;

    // 把基于当前节点的本地坐标系下的坐标转换到世界坐标系中
    Point convertToWorldSpace(const Point& nodePoint) const;

    // 基于Anchor Point把基于当前节点的本地坐标系下的坐标转换到世界坐标系中
    Point convertToNodeSpaceAR(const Point& worldPoint) const;

    // 基于Anchor Point把世界坐标转换到当前节点的本地坐标系中
    Point convertToWorldSpaceAR(const Point& nodePoint) const;

下面通过一个例子来说明这四个方法的理解和作用:

auto *sprite1 = Sprite::create("HelloWorld.png");
    sprite1->setPosition(ccp(20,40));
    sprite1->setAnchorPoint(ccp(0,0));
    this->addChild(sprite1);  //此时添加到的是世界坐标系,也就是OpenGL坐标系

    auto *sprite2 = Sprite::create("HelloWorld.png");
    sprite2->setPosition(ccp(-5,-20));
    sprite2->setAnchorPoint(ccp(1,1));
    this->addChild(sprite2); //此时添加到的是世界坐标系,也就是OpenGL坐标系

    //将 sprite2 这个节点的坐标ccp(-5,-20) 转换为 sprite1节点 下的本地(节点)坐标系统的 位置坐标
    Point point1 = sprite1->convertToNodeSpace(sprite2->getPosition());

    //将 sprite2 这个节点的坐标ccp(-5,-20) 转换为 sprite1节点 下的世界坐标系统的 位置坐标
    Point point2 = sprite1->convertToWorldSpace(sprite2->getPosition());

    log("position = (%f,%f)",point1.x,point1.y);
    log("position = (%f,point2.x,point2.y);
运行结果:

Cocos2d: position = (-25.000000,-60.000000)
Cocos2d: position = (15.000000,20.000000)

其中:Point point1 = sprite1->convertToNodeSpace(sprite2->getPosition());

相当于sprite2这个节点添加到(实际没有添加,只是这样理解)sprite1这个节点上,那么就需要使用sprite1这个节点的节点坐标系统,这个节点的节点坐标系统的原点在(20,40),而sprite1的坐标是(-5,-20),那么经过变换之后,sprite1的坐标就是(-25,-60)。

Point point2 = sprite1->convertToWorldSpace(sprite2->getPosition());

此时的变换是将sprite2的坐标转换到sprite1的世界坐标系下,而其中世界坐标系是没有变化的,始终都是和OpenGL等同,只不过sprite2在变换的时候将sprite1作为了”参照“而已。所以变换之后sprite2的坐标为:(15,20)。


动作

原理介绍

动作作用于Node,因此每个动作都需要由Node对象执行。动作类(Action)作为基类,实际上是一个接口,动作类的大多数实现类都派生于有限时间动作类(FiniteTimeAction)。在实际开发中我们通常用到两类动作-即时动作和持续动作,它们均继承于有限时间动作类。

一、即时动作

是在下一帧立刻完成的动作,如设定位置、设定缩放等。把它们包装成动作后,可以与其他动作类组合为复杂动作。

Place: 将节点放置到某个指定位置,其作用与修改节点的position属性相同。

auto placeAction = Place::create(Point(10,10));

FlipX和FlipY: 将精灵沿X轴和Y轴反向显示。

auto flipxAction = FlipX::create(true);
    auto moveTo = MoveTo::create(0.4f,Point(0,0));
    auto action = Sequence::create(moveTo,flipxAction,moveTo->reverse(),NULL);//将精灵移动到一端后反向显示再移回原点

Show和Hide: 显示和隐藏节点,其作用与设置节点的visible属性作用一样。

auto hideAction = Hide::create();
    auto moveTo = MoveTo::create(0.4f,hideAction,NULL);

CallFunc: 包括CallFunc、CallFuncN两个动作,用来在动作中进行方法调用。

为了节约内存资源,可以在动作完成后调用相应函数清理内存auto actionMoveDone = CallFuncN::create([&](Ref* sender){
        log("Clear memory");
    });
    auto moveTo = MoveTo::create(0.4f,actionMoveDone,NULL);//

二、持续动作

1) 属性变化动作:通过属性值的逐渐变化来实现动画效果。XXTo是表示最终值,而XXBy则表示向量即改变值。

MoveTo和MoveBy:在规定时间内做直线运动到某个位置。

MoveTo::create(float duration,const Point& position); //绝对位置
    MoveBy::create(float duration,const Point& position); //相对位置

JumpTo和JumpBy:以一定的轨迹跳跃到指定位置。

JumpTo::create(float duration,const Point& position,float height,int jumps);
    JumpBy::create(float duration,int jumps);

BezierTo和BezierBy:进行贝塞尔曲线运动。

每条贝塞尔曲线都包含一个起点和一个终点。起点和终点各自包含一个控制点,而控制点到端点的连线称作控制线。控制点决定了曲线的形状,包含角度和长度两个参数。如下图:

ccBezierConfig bezier; //1. 创建ccBezierConfig结构体
    bezier.controlPoint_1 = Point(0,0); //2. 控制点1
    bezier.controlPoint_2 = Point(100,100); //3. 控制点2
    bezier.endPosition = Point(50,100); //4. 设置终点
    auto bezierAction = BezierTo::create(0.5f,bezier); //5. 把结构体传入BezierTo或BezierBy的初始化方法中

ScaleTo和ScaleBy: 缩放效果,使节点的缩放系数随时间线性变化。

ScaleTo::create(float duration,float s);
    ScaleBy::create(float duration,float s);

RotateTo和RotateBy: 旋转效果

RotateTo::create(float duration,float deltaAngle);
    RotateBy::create(float duration,float deltaAngle);

2)视觉特效动作

FadeIn,FadeOut和FateTo:产生淡入淡出效果,和透明变化效果,对应的初始化方法为:

FadeIn::create(float d);    淡入
    FadeOut::create(float d);    淡出 
    FadeTo::create(float duration,GLubyte opacity); 一定时间内透明度变化

TintTo和TintBy: 色调变化。

TintTo::create(float duration,GLubyte red,GLubyte green,GLubyte blue);
    TintBy::create(float duration,GLubyte blue);

Blink: 使节点闪烁,并制定闪烁次数。

Blink::create(float duration,int blinks);

Animation: 实现帧动画效果.

//手动创建动画
    auto animation = Animation::create();
    for( int i=1;i<15;i++)
    {
        char szName[100] = {0};
        sprintf(szName,"sprite_%02d.png",i);
        animation->addSpriteFrameWithFile(szName);
    }

    animation->setDelayPerUnit(2.8f / 14.0f);
    animation->setRestoreOriginalFrame(true);

    auto action = Animate::create(animation); //动画创建后需要一个动画播放器Animate来播放这些动画
    sprite->runAction(Sequence::create(action,action->reverse(),NULL));

    //文件创建动画
    auto cache = AnimationCache::getInstance();
    cache->addAnimationsWithFile("animation.plist");
    auto animation2 = cache->getAnimation("dance_1");

    auto action2 = Animate::create(animation2);
    sprite->runAction(Sequence::create(action2,action2->reverse(),NULL));

3)复合动作

复合动作即将各种动作组合起来再让节点执行,复合动作本身也可以作为一个普通动作嵌入到其他动作中。

注意:Sequence动作不能嵌入其他复合动作内使用,DelayTime不属于复合动作,但是只能在复合动作内使用。

DelayTime: 延时动作其实什么都不做,提供一段空白期,它只有一个初始化方法:

DelayTime::create(float d);

Repeat/RepeatForever: 反复执行某个动作,通常我们用Repeat和RepeatForever这两个方法执行:

Repeat::create(FiniteTimeAction *action,unsigned int times);
    RepeatForever::create(ActionInterval *action);

Spawn: 使一批动作同时执行。

Spawn::create(FiniteTimeAction *action1,...);
    Spawn::create(const Vector<FiniteTimeAction*>& arrayOfActions);

Sequence: 让各种动作有序执行。

Sequence::create(FiniteTimeAction *action1,...);
    Sequence::create(const Vector<FiniteTimeAction*>& arrayOfActions);

4)变速动作 把任何动作按照改变后的速度执行。

Speed: 线性的改变某个动作的速度,为了改变一个动作的速度,首先需要将目标动作包装到Speed动作中:

auto repeat = RepeatForever::create(animation);
    auto speed = Speed::create(repeat,0.5f); //第二个参数为变速比例,设置为0.5f则速度为原来一半。
    sprite->runAction(speed);

ActionEase: 实现动作的速度又快到慢、速度随时间改变的匀速运动。该类包含5类运动:指数缓冲、Sine缓冲、弹性缓冲、跳跃缓冲和回震缓冲。每类运动都包含3个不同时期的变换:In、Out和InOut。以下以InSine为例:

auto sineIn = EaseSineIn::create(action);
    sprite->runAction(sineIn);

序列帧动画

简介

Cocos2d-x中,动画的具体内容是依靠精灵显示出来的,为了显示动态图片,我们需要不停切换精灵显示的内容,通过把静态的精灵变为动画播放器从而实现动画效果。动画由帧组成,每一帧都是一个纹理,我们可以使用一个纹理序列来创建动画。

Animation类描述一个动画;Animate播放动画,并由精灵执行。

一、创建方法

## 手动添加序列帧到Animation类

1)将每一帧要显示的精灵有序添加到Animation类中,并设置每帧的播放时间,让动画能够匀速播放。

2)通过setRestoreOriginalFrame来设置是否在动画播放结束后恢复到第一帧。

3)创建好Animation实例后,需要创建一个Animate实例来播放序列帧动画。

auto animation = Animation::create();
    for( int i=1;i<15;i++)
    {
        char szName[100] = {0};
        sprintf(szName,"Images/grossini_dance_%02d.png",i);
        animation->addSpriteFrameWithFile(szName); //添加精灵帧到Animation实例
    }
    // should last 2.8 seconds. And there are 14 frames.
    animation->setDelayPerUnit(2.8f / 14.0f); //设置每一帧持续时间,以秒为单位
    animation->setRestoreOriginalFrame(true); //设置是否在动画播放结束后恢复到第一帧

    auto action = Animate::create(animation);
    _grossini->runAction(Sequence::create(action,NULL));

## 通过文件添加Animation类

plist文件里保存了组成动画的相关信息,通过该类获取到plist文件里的动画。通过动画缓存类AnimationCache可以加载xml/plist文件,用Animate实例来播放序列帧动画。。AnimationCache类接口:

  • addAnimationsWithFile,添加动画文件到缓存,plist文件
  • getAnimation,从缓存中获取动画对象
  • getInstance,获取动画缓存实例对象
 auto cache = AnimationCache::getInstance();  cache->addAnimationsWithFile("animations/animations-2.plist"); auto animation2 = cache->getAnimation("dance_1"); auto action2 = Animate::create(animation2); _tamara->runAction(Sequence::create(action2,NULL));

二、动画缓存(AnimationCache)

通常情况下,对于一个精灵动画,每次创建时都需要加载精灵帧,按顺序添加到数组,再创建对应动作类,这是一个非常烦琐的计算过程。对于使用频率高的动画,比如走路动画,利用动画缓存可以有效降低每次创建的巨大消耗

  • static AnimationCache* getInstance(); //全局共享的单例
  • void addAnimation(Animation *animation,const std::string& name); //添加一个动画到缓存
  • void addAnimationsWithFile(const std::string& plist); //添加动画文件到缓存
  • void removeAnimation(const std::string& name); //移除一个指定的动画
  • Animation* getAnimation(const std::string& name); //获得事先存入的动画

建议:在内存警告时,应该加入内存清理缓存(按照引用层级由高到低,以保证释放引用有效。)

void releaseCaches()
{
    AnimationCache::destroyInstance(); //先清理动画缓存
    SpriteFrameCache::getInstance()->removeUnusedSpriteFrames(); //后清理精灵帧缓存
    TextureCache::getInstance()->removeUnuserdTextures(); //最后清理纹理缓存
}

三、场景转换(Transitions)

场景之间通过TransitionScene系列类来实现过渡跳转的效果。TransitionScene继承于Scene,该系列类主要是与场景切换特效相关的一些使用类。

下图是TransitionScene的类关系图:

主要的切换特效有:

  • TransitionRotoZoom 旋转进入
  • TransitionJumpZoom 跳动进入
  • TransitionPageTurn 翻页效果进入
  • TransitionRadialCCW 钟摆效果
  • TransitionMoveInL / TransitionMoveInR / TransitionMoveInT / TransitionMoveInB 左侧/右侧/顶部/底部进入
  • TransitionSlideInL/TransitionSlideInR/TransitionSlideInT/TransitionSlideInB 分别从左侧/右侧/顶部/底部滑入
  • TransitionShrinkGrow 交替进入
  • TransitionFlipX/TransitionFlipY x轴翻入(左右)/ y轴翻入(上下)
  • TransitionFlipAngular 左上右下轴翻入
  • TransitionZoomFlipX/TransitionZoomFlipY x轴翻入放大缩小效果(左右)/ y轴翻入放大缩小效果(上下)
  • TransitionFadeTR /TransitionFadeBL/TransitionFadeUp/TransitionFadeDown 小方格右上角显示进入/ 小方格左下角显示进入/ 横条向上显示进入/ 横条向下显示进入
  • TransitionSplitCols / TransitionSplitRows 竖条切换进入/ 横条切换进入
  • TransitionZoomFlipAngular 左上右下轴翻入放大缩小效果
  • TransitionFade 渐隐进入
  • TransitionCrossFade 渐变进入
  • TransitionTurnOffTiles 小方格消失进入
  • TransitionRadialCCW/TransitionRadialCW 扇面展开收起

等等,更多效果可查看官方API。场景转换的实现:

auto transitions = TransitionMoveInL::create(0.2f,scene);
Director::getInstance()->replaceScene(transitions);

场景的转换是由Director类来控制的,通过调用Director类的replaceScene( Scenescene ) 方法可直接使用传入的scene替换当前场景来切换画面,当前场景会被释放,它是切换场景时最常用的方法。
前面说过,场景转换的一系列类都继承于Scene类,所以可以创建一个转场类替代scene,从而实现各种转场的效果。
`static TransitionMoveInL
create(float t,Scene* scene);`方法中t表示转场到scene的时间。


Cocos2d-x 多分辨率适配完全解析

3.0中有以下相关接口:

Director::getInstance()->getOpenGLView()->setDesignResolutionSize() //设计分辨率大小及模式
Director::getInstance()->setContentScaleFactor()  //内容缩放因子
FileUtils::getInstance()->setSearchPaths()  //资源搜索路径
Director::getInstance()->getOpenGLView()->getFrameSize() //屏幕分辨率
Director::getInstance()->getWinSize()  //设计分辨率
Director::getInstance()->getVisibleSize() //设计分辨率可视区域大小
Director::getInstance()->getVisibleOrigin() //设计分辨率可视区域起点

从cocos2d-2.1beta3-x-2.1.1开始,

CCFileUtils::sharedFileUtils()->setResourceDirectory()被新接口FileUtils::getInstance()->setSearchPaths(searchPath)替代

从Cocos2d-x 2.1.3开始,新加入了两种ResolutionPolicy(kResolutionFixedHeight, kResolutionFixedWidth),共5中模式。

官方分别在Multi_resolution_supportMechanism_of_loading_resources有介绍。

资源分辨率,设计分辨率,屏幕分辨率

Resources width 以下简写为RW,Resources height 以下简写为RH

Design width 以下简写为DW,Design height 以下简写为DH

Screen width 以下简写为SW,Screen height 以下简写为SH

从资源分辨率到设计分辨率

setContentScaleFactor()决定了图片显示到屏幕的缩放因子,这个因子是资源宽、高比设计分辨率宽、高。

setContentScaleFactor()通常有两个方式来设置参数。 RH/DH或RW/DW,不同的因子选择有不同的缩放负作用。

从设计分辨率到屏幕分辨率

setDesignResolutionSize(DW,DH,resolutionPolicy)

ResolutionPolicy::EXACT_FIT

ResolutionPolicy::SHOW_ALL

屏幕宽、高分别和设计分辨率宽、高计算缩放因子,取较(小)者作为宽、高的缩放因子。保证了全部显示到屏幕,但可能会有黑边。

ResolutionPolicy::EXACT_FIT

屏幕宽 与 设计宽比 作为X方向的缩放因子,屏幕高 与 设计高比 作为Y方向的缩放因子。保证完全铺满屏幕,但是可能会变形。

ResolutionPolicy::NO_BORDER

屏幕宽、高分别和设计分辨率宽、高计算缩放因子,取较(大)者作为宽、高的缩放因子。保证总能有一个方向上铺满屏幕,而另一个方向一般会超出屏幕区域。

ResolutionPolicy::FIXED_HEIGHT

根据屏幕分辨率修正设计分辨率的宽度。适合高方向需要撑满,宽方向可裁减的游戏,结合setContentScaleFactor(RH/DH)使用。

ResolutionPolicy::FIXED_WIDTH

根据屏幕分辨率修正设计分辨率的高度。适合宽方向需要撑满,高方向可裁减的游戏,结合setContentScaleFactor(RW/DW)使用。

ResolutionPolicy::FIXED_HEIGHT和ResolutionPolicy::FIXED_WIDTH:会在内部修正传入设计分辨率,以保证屏幕分辨率到设计分辨率无拉伸铺满屏幕。

ResolutionPolicy::NO_BORDER情况下,设计分辨率并不是可见区域,我们布局精灵需要根据VisibleOrigin和VisibleSize来做判断处理。

ResolutionPolicy::FIXED_HEIGHT则不同,设计分辨率就是可见区域,VisibleOrigin总是(0,0)

getVisibleSize() = getWinSize(),ResolutionPolicy::FIXED_HEIGHT达到了同样的目的,但是却简化了代码。

ResolutionPolicy::FIXED_HEIGHT和ResolutionPolicy::FIXED_WIDTH是ResolutionPolicy::NO_BORDER的进化,新项目中建议立即开始使用这两种方式。

ClippingNode的使用

概述

ClippingNode(裁剪节点)可以用来对节点进行裁剪,可以根据一个模板切割图片的节点,生成任何形状的节点显示。

ClippingNode是Node的子类,可以像普通节点一样放入Layer,Scene,Node中。

  • ClippingNode 原理:

    ClippingNode是利用模板遮罩来完成对Node区域裁剪的技术。如何理解ClippingNode的遮罩?看下图的例子吧。

    所谓模板,就是一个形状,透过该形状可看到底板上的图层,如果底板上没有任何内容,则直接看到Layer上的内容,而底板上的东西又不会妨碍Layer上的东西,即模板在底板之外的空间对于Layer来说是透明的。

ClippingNode 常用方法

  1. create

    可以使用static ClippingNode* create();方法创建一个ClippingNode对象。如下:

    auto clipper = ClippingNode::create();

    也可以使用static ClippingNode* create(Node *stencil);方法创建;在创建的时候指定裁剪模板

    auto stencil = Sprite::create("CloseNormal.png");//模板节点
    clipper = ClippingNode::create(stencil);
  2. setStencil 可以使用void setStencil(Node *stencil);方法设置“裁剪模板”节点。 如下:

    clipper->setStencil(stencil);//设置裁剪模板
  3. setInverted

    可以使用void setInverted(bool inverted);方法,设置是显示被裁剪的部分,还是显示裁剪。true 显示剩余部分。false显示被剪掉部分。 如下:

    clipper->setInverted(true);//设置底板可见,显示剩余部分
  4. setAlphaThreshold

    可以使用void setAlphaThreshold(GLfloat alphaThreshold);,设置alpha阈值, 只有模板(stencil)的alpha像素大于alpha阈值(alphaThreshold)时内容才会被绘制。 alpha阈值(threshold)范围应是0到1之间的浮点数。 alpha阈值(threshold)默认为1。 如下:

    clipper->setAlphaThreshold(0);//设置绘制底板的Alpha值为0

ClippingNode示例

auto bg = LayerColor::create(Color4B(255,255));
    this->addChild(bg,-1);//1

    auto stencil = Sprite::create("CloseNormal.png");
    stencil->setScale(2);//2
    auto clipper = ClippingNode::create();
    clipper->setStencil(stencil);//设置裁剪模板 //3
    clipper->setInverted(true);//设置底板可见
    clipper->setAlphaThreshold(0);//设置绘制底板的Alpha值为0
    this->addChild(clipper);//4

    auto content = Sprite::create("HelloWorld.png");//被裁剪的内容
    clipper->addChild(content);//5

    clipper->setPosition(Vec2(visibleSize.width/2 + origin.x,visibleSize.height/2 + origin.y));
  1. 添加了一个白色的LayerColor作为背景层。
  2. 创建一个精灵,作为裁剪模板,并放大2倍
  3. 创建ClippingNode节点,并设置裁剪模板
  4. 设置裁剪显示,Alpha阈值,并将裁剪节点加到层中
  5. 设置被裁剪的内容

运行效果如图:

clipper->setInverted(true);改为clipper->setInverted(false);运行效果如图:

  • 资源图片



声明:本文是对http://www.cocos.com/帮助文档的阅读笔记。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是