首页 > 代码库 > Cocos2d-x 3.2 学习笔记(五)Sprite Node

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

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

涉及到的类Class:

AnimationFrame 动画帧。

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

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

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

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

SpriteFrame 一个精灵帧。

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

下面依次说下用法

/************************************************************************//*Sprite定义为二维图像可以通过一个图像或一个图像的矩形裁剪部分创建SpriteSprite的默认锚点(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定义为二维图像可以通过一个图像或一个图像的矩形裁剪部分创建SpriteSprite的默认锚点(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