zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    html+css设计简单的博客首页
    js基础知识总结(一)
    css基础知识总结
    HTML基础知识
    链表常见题目--附具体分析和代码
    程序的内存分配
    python线程互斥锁递归锁死锁
    动态规划算法python实现
    ECMAScript 6 开篇准备
    弦生成器
  • 原文地址:https://www.cnblogs.com/Richard-Core/p/3864095.html
Copyright © 2011-2022 走看看