(五)Sprite Node

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


涉及到的类Class:

  • AnimationFrame 动画帧。

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

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

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

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

  • SpriteFrame 一个精灵帧。

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


下面依次说下用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/************************************************************************/
/*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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/************************************************************************/
/* 一个精灵帧包括:
 
纹理:一个被精灵使用的二维纹理
矩形:一个纹理矩形                                                                     */
/************************************************************************/
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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/************************************************************************/
/* 处理精灵帧的载入的单例。 它将精灵帧保存在缓存里。
    只需要加载一次文件,在多个地方通过名字或标记就可以直接使用纹理和精灵帧
*/
/************************************************************************/
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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/************************************************************************/
/*
    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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/************************************************************************/
/* 一个用来在精灵对象上表现动画的动画对象
动画对象包含动画帧对象, 还可能有一个设定这些帧之间延迟的参数. 
你可以用动画动作(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_d",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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/************************************************************************/
/* 动画缓存单例类。 如何你想要保存动画,你需要使用这个缓存
*/
/************************************************************************/
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;
}

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


这是我写的测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#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_d",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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值