Cocos2d-x 3.2 学习笔记(五)Sprite Node

游戏中最重要的元素Sprite精灵,关于精灵的创建,精灵的控制等等。

涉及到的类Class:

AnimationFrame 动画帧。

Animation 动画对象;一个用来在精灵对象上表现动画的动画对象。

AnimationCache 动画缓存单例类。 如何你想要保存动画,你需要使用这个缓存。

Sprite 精灵;定义为二维图像。

SpriteBatchNode 与批量节点类似,如果包含子节点会在一次OpenGL调用内绘制完成。

SpriteFrame 一个精灵帧。

SpriteFrameCache 处理精灵帧的载入的单例。 它将精灵帧保存在缓存里。

下面依次说下用法

/************************************************************************/
/*Sprite定义为二维图像
可以通过一个图像或一个图像的矩形裁剪部分创建Sprite
Sprite的默认锚点(anchorPoint)为(0.5, 0.5)。

*/
/************************************************************************/
Sprite* SpriteNodeTest::createSpriteByPath()
{
    auto sprite = Sprite::create("grossinis_sister2.png");
    auto size = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    sprite->setPosition(Vec2(size.width/2 + origin.x, size.height/2 + origin.y));
    return sprite;
}
/************************************************************************/
/* 一个精灵帧包括:

纹理:一个被精灵使用的二维纹理
矩形:一个纹理矩形                                                                     */
/************************************************************************/
Sprite* SpriteNodeTest::createSpriteBySpriteFrame()
{
    auto sFrame = SpriteFrame::create("grossinis_sister2.png",Rect(0,0,56,138));
    auto sprite = Sprite::createWithSpriteFrame(sFrame);
    auto size = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    sprite->setPosition(Vec2(size.width/2 + origin.x, size.height/2 + origin.y));
    return sprite;
}
/************************************************************************/
/* 处理精灵帧的载入的单例。 它将精灵帧保存在缓存里。
    只需要加载一次文件,在多个地方通过名字或标记就可以直接使用纹理和精灵帧
*/
/************************************************************************/
Sprite* SpriteNodeTest::createSpriteBySpriteFrameCache()
{
    auto cache = SpriteFrameCache::getInstance();
    cache->addSpriteFramesWithFile("grossini-aliases.plist");
    auto sFrame = cache->getSpriteFrameByName("grossini_dance_01.png");
    auto sprite = Sprite::createWithSpriteFrame(sFrame);
    auto size = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    sprite->setPosition(Vec2(size.width/2 + origin.x, size.height/2 + origin.y));
    return sprite;
}
/************************************************************************/
/*
    SpriteBatchNode与批量节点类似,如果包含子节点会在一次OpenGL调用内绘制完成
    一个SpriteBatchNode可以引用一个且只有一个纹理(一个图像文件或一个纹理集),只有包含该纹理的Sprite可以加入到SpriteBatchNode中。 
    加入SpriteBatchNode的所有Sprite在一次OpenGL ES调用内绘制完成,而未加入SpriteBatchNode的Sprite每一个都需要单独调用OpenGL ES绘制,
    这样效率比较低。这个可以自己去试一下效果做个对比就能看出。
*/
/************************************************************************/
SpriteBatchNode* SpriteNodeTest::createSpriteBySpriteBatchNode()
{
    auto size = Director::getInstance()->getVisibleSize();
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("grossini-aliases.plist");
    auto sBatch = SpriteBatchNode::create("grossini-aliases.png");
    for (int len = 0; len < 250; len++)
    {
        auto sprite = Sprite::createWithSpriteFrameName("grossini_dance_01.png");
        sprite->setPosition(Vec2(CCRANDOM_0_1()*size.width,CCRANDOM_0_1()*size.height));
        sBatch->addChild(sprite);
    }
    return sBatch;
}
/************************************************************************/
/* 一个用来在精灵对象上表现动画的动画对象
动画对象包含动画帧对象, 还可能有一个设定这些帧之间延迟的参数. 
你可以用动画动作(Animate action)来创建一个动画对象
*/
/************************************************************************/
Sprite* SpriteNodeTest::createSpriteByAnimation()
{
    auto size = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    auto cache = SpriteFrameCache::getInstance();
    cache->addSpriteFramesWithFile("grossini-aliases.plist");

    auto sprite = Sprite::createWithSpriteFrameName("grossini_dance_01.png");
    sprite->setPosition(Vec2(size.width/2 + origin.x, size.height/2 + origin.y));
    
    Vector<SpriteFrame*> aFrames(15);
    char sFrameName[100]={0};
    for (int len = 1;len < 15; len++)
    {
        sprintf(sFrameName,"dance_%02d",len);
        auto sFrame = cache->getSpriteFrameByName(sFrameName);
        aFrames.pushBack(sFrame);
    }
    auto animation = Animation::createWithSpriteFrames(aFrames,0.3f);
    sprite->runAction(RepeatForever::create(Animate::create(animation)));

    return sprite;
}
/************************************************************************/
/* 动画缓存单例类。 如何你想要保存动画,你需要使用这个缓存
*/
/************************************************************************/
Sprite* SpriteNodeTest::createSpriteByAnimationCache()
{
    auto size = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    auto cache = SpriteFrameCache::getInstance();
    //缓存animations要用到的资源
    cache->addSpriteFramesWithFile("grossini-aliases.plist","grossini-aliases.png");

    auto sprite = Sprite::createWithSpriteFrameName("grossini_dance_01.png");
    sprite->setPosition(Vec2(size.width/2 + origin.x, size.height/2 + origin.y));

    auto aCache = AnimationCache::getInstance();
    //animations里面包含动画信息和名字,要确保animations包含的资源已经在SpriteFrameCache里面缓存
    aCache->addAnimationsWithFile("animations-2.plist");
    sprite->runAction(RepeatForever::create(Animate::create(aCache->animationByName("dance_1"))));
    return sprite;
}

上面就是基本的用法,当然这很粗浅,更深的用法以及工具类,慢慢研究吧!

这是我写的测试类:

#ifndef __SpriteNodeTest__
#define __SpriteNodeTest__

#include "cocos2d.h"
USING_NS_CC;

class SpriteNodeTest : public cocos2d::Layer
{
public:
    static cocos2d::Scene* createScene();
    CREATE_FUNC(SpriteNodeTest);
    virtual bool init(); 
    static Sprite* createSpriteByPath();
    static Sprite* createSpriteBySpriteFrame();
    static Sprite* createSpriteBySpriteFrameCache();
    static SpriteBatchNode* createSpriteBySpriteBatchNode();
    static Sprite* createSpriteByAnimation();
    static Sprite* createSpriteByAnimationCache();
protected:
    bool onTouchBeganFun(Touch* touch,Event* ev);
};

#endif
SpriteNodeTest.h
#include "SpriteNodeTest.h"

std::function<Node*()> demotest[]=
{
    SpriteNodeTest::createSpriteByPath,
    SpriteNodeTest::createSpriteBySpriteFrame,
    SpriteNodeTest::createSpriteBySpriteFrameCache,
    SpriteNodeTest::createSpriteBySpriteBatchNode,
    SpriteNodeTest::createSpriteByAnimation,
    SpriteNodeTest::createSpriteByAnimationCache
};

Scene* SpriteNodeTest::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();

    // 'layer' is an autorelease object
    auto layer = SpriteNodeTest::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

bool SpriteNodeTest::init()
{
    auto event = EventListenerTouchOneByOne::create();
    event->onTouchBegan = CC_CALLBACK_2(SpriteNodeTest::onTouchBeganFun,this);
    this->_eventDispatcher->addEventListenerWithSceneGraphPriority (event,this);

    createSpriteByPath();
    return true;
}
#define MAX_LAYER    (sizeof(demotest) / sizeof(demotest[0]))
int index=0;
bool SpriteNodeTest::onTouchBeganFun(Touch* touch,Event* ev)
{
    index++;
    index = index % MAX_LAYER;

    this->removeAllChildren();
    auto sprite = demotest[index]();
    this->addChild(sprite);
    return true;
}

/************************************************************************/
/*Sprite定义为二维图像
可以通过一个图像或一个图像的矩形裁剪部分创建Sprite
Sprite的默认锚点(anchorPoint)为(0.5, 0.5)。

*/
/************************************************************************/
Sprite* SpriteNodeTest::createSpriteByPath()
{
    auto sprite = Sprite::create("grossinis_sister2.png");
    auto size = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    sprite->setPosition(Vec2(size.width/2 + origin.x, size.height/2 + origin.y));
    return sprite;
}


/************************************************************************/
/* 一个精灵帧包括:

纹理:一个被精灵使用的二维纹理
矩形:一个纹理矩形                                                                     */
/************************************************************************/
Sprite* SpriteNodeTest::createSpriteBySpriteFrame()
{
    auto sFrame = SpriteFrame::create("grossinis_sister2.png",Rect(0,0,56,138));
    auto sprite = Sprite::createWithSpriteFrame(sFrame);
    auto size = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    sprite->setPosition(Vec2(size.width/2 + origin.x, size.height/2 + origin.y));
    return sprite;
}
/************************************************************************/
/* 处理精灵帧的载入的单例。 它将精灵帧保存在缓存里。
    只需要加载一次文件,在多个地方通过名字或标记就可以直接使用纹理和精灵帧
*/
/************************************************************************/
Sprite* SpriteNodeTest::createSpriteBySpriteFrameCache()
{
    auto cache = SpriteFrameCache::getInstance();
    cache->addSpriteFramesWithFile("grossini-aliases.plist");
    auto sFrame = cache->getSpriteFrameByName("grossini_dance_01.png");
    auto sprite = Sprite::createWithSpriteFrame(sFrame);
    auto size = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    sprite->setPosition(Vec2(size.width/2 + origin.x, size.height/2 + origin.y));
    return sprite;
}
/************************************************************************/
/*
    SpriteBatchNode与批量节点类似,如果包含子节点会在一次OpenGL调用内绘制完成
    一个SpriteBatchNode可以引用一个且只有一个纹理(一个图像文件或一个纹理集),只有包含该纹理的Sprite可以加入到SpriteBatchNode中。 
    加入SpriteBatchNode的所有Sprite在一次OpenGL ES调用内绘制完成,而未加入SpriteBatchNode的Sprite每一个都需要单独调用OpenGL ES绘制,
    这样效率比较低。这个可以自己去试一下效果做个对比就能看出。
*/
/************************************************************************/
SpriteBatchNode* SpriteNodeTest::createSpriteBySpriteBatchNode()
{
    auto size = Director::getInstance()->getVisibleSize();
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("grossini-aliases.plist");
    auto sBatch = SpriteBatchNode::create("grossini-aliases.png");
    for (int len = 0; len < 250; len++)
    {
        auto sprite = Sprite::createWithSpriteFrameName("grossini_dance_01.png");
        sprite->setPosition(Vec2(CCRANDOM_0_1()*size.width,CCRANDOM_0_1()*size.height));
        sBatch->addChild(sprite);
    }
    return sBatch;
}
/************************************************************************/
/* 一个用来在精灵对象上表现动画的动画对象
动画对象包含动画帧对象, 还可能有一个设定这些帧之间延迟的参数. 
你可以用动画动作(Animate action)来创建一个动画对象
*/
/************************************************************************/
Sprite* SpriteNodeTest::createSpriteByAnimation()
{
    auto size = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    auto cache = SpriteFrameCache::getInstance();
    cache->addSpriteFramesWithFile("grossini-aliases.plist");

    auto sprite = Sprite::createWithSpriteFrameName("grossini_dance_01.png");
    sprite->setPosition(Vec2(size.width/2 + origin.x, size.height/2 + origin.y));
    
    Vector<SpriteFrame*> aFrames(15);
    char sFrameName[100]={0};
    for (int len = 1;len < 15; len++)
    {
        sprintf(sFrameName,"dance_%02d",len);
        auto sFrame = cache->getSpriteFrameByName(sFrameName);
        aFrames.pushBack(sFrame);
    }
    auto animation = Animation::createWithSpriteFrames(aFrames,0.3f);
    sprite->runAction(RepeatForever::create(Animate::create(animation)));

    return sprite;
}
/************************************************************************/
/* 动画缓存单例类。 如何你想要保存动画,你需要使用这个缓存
*/
/************************************************************************/
Sprite* SpriteNodeTest::createSpriteByAnimationCache()
{
    auto size = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    auto cache = SpriteFrameCache::getInstance();
    //缓存animations要用到的资源
    cache->addSpriteFramesWithFile("grossini-aliases.plist","grossini-aliases.png");

    auto sprite = Sprite::createWithSpriteFrameName("grossini_dance_01.png");
    sprite->setPosition(Vec2(size.width/2 + origin.x, size.height/2 + origin.y));

    auto aCache = AnimationCache::getInstance();
    //animations里面包含动画信息和名字,要确保animations包含的资源已经在SpriteFrameCache里面缓存
    aCache->addAnimationsWithFile("animations-2.plist");
    sprite->runAction(RepeatForever::create(Animate::create(aCache->animationByName("dance_1"))));
    return sprite;
}
SpriteNodeTest.cpp
原文地址:https://www.cnblogs.com/Richard-Core/p/3864095.html