CCActionNode.cpp

NC1988, 2013-12-09 10:02

Download (12.2 kB)

 
1
/****************************************************************************
2
Copyright (c) 2013 cocos2d-x.org
3

    
4
http://www.cocos2d-x.org
5

    
6
Permission is hereby granted, free of charge, to any person obtaining a copy
7
of this software and associated documentation files (the "Software"), to deal
8
in the Software without restriction, including without limitation the rights
9
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
copies of the Software, and to permit persons to whom the Software is
11
furnished to do so, subject to the following conditions:
12

    
13
The above copyright notice and this permission notice shall be included in
14
all copies or substantial portions of the Software.
15

    
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
THE SOFTWARE.
23
****************************************************************************/
24

    
25
#include "CCActionNode.h"
26
#include "CCActionFrameEasing.h"
27
#include "CCActionObject.h"
28
#include "../GUI/BaseClasses/UIWidget.h"
29
#include "../GUI/System/UIHelper.h"
30
#include "../Json/DictionaryHelper.h"
31

    
32
NS_CC_EXT_BEGIN
33

    
34
        ActionNode::ActionNode()
35
        : currentFrameIndex(0)
36
        , destFrameIndex(0)
37
        , m_fUnitTime(0.1f)
38
        , m_ActionTag(0)
39
        , m_Object(NULL)
40
        , m_actionSpawn(NULL)
41
        , m_action(NULL)
42
        , m_FrameArray(NULL)
43
        , frameArrayNum(0)
44
{
45
        m_FrameArray = CCArray::create();
46
        m_FrameArray->retain();
47

    
48
        frameArrayNum = (int)kKeyframeMax;
49
        for(int i = 0; i < frameArrayNum; i++)
50
        {
51
                CCArray* cArray = CCArray::create();
52
                m_FrameArray->addObject(cArray);
53
        }
54
}
55

    
56
ActionNode::~ActionNode()
57
{
58
        if (m_action == NULL)
59
        {
60
                CC_SAFE_RELEASE_NULL(m_actionSpawn);
61
        }
62
        else
63
        {
64
                CC_SAFE_RELEASE_NULL(m_action);
65
        }
66

    
67
        if (m_FrameArray != NULL)
68
        {
69
                for( int i = 0; i < frameArrayNum; i++ )
70
                {
71
                        CCArray* arr = (CCArray*)m_FrameArray->objectAtIndex(i);
72
                        for( int j = 0; j < arr->count(); j++ )
73
                        {
74
                                arr->objectAtIndex( j )->release();
75
                        }
76
                        arr->removeAllObjects();
77
                }
78

    
79
                m_FrameArray->removeAllObjects();
80
                CC_SAFE_RELEASE_NULL(m_FrameArray);
81
        }
82

    
83
}
84

    
85
void ActionNode::initWithDictionary(cs::CSJsonDictionary *dic,CCObject* root)
86
{
87
        setActionTag(DICTOOL->getIntValue_json(dic, "ActionTag"));
88
        int actionFrameCount = DICTOOL->getArrayCount_json(dic, "actionframelist");
89
        for (int i=0; i<actionFrameCount; i++) {
90

    
91
                cs::CSJsonDictionary* actionFrameDic = DICTOOL->getDictionaryFromArray_json(dic, "actionframelist", i);
92
                int frameInex = DICTOOL->getIntValue_json(actionFrameDic,"frameid");
93

    
94
                bool existPosition = DICTOOL->checkObjectExist_json(actionFrameDic,"positionx");
95
                if (existPosition)
96
                {
97
                        float positionX = DICTOOL->getFloatValue_json(actionFrameDic, "positionx");
98
                        float positionY = DICTOOL->getFloatValue_json(actionFrameDic, "positiony");
99
                        ActionMoveFrame* actionFrame = new ActionMoveFrame();
100
                        actionFrame->setFrameIndex(frameInex);
101
                        actionFrame->setPosition(CCPointMake(positionX, positionY));
102
                        CCArray* cActionArray = (CCArray*)m_FrameArray->objectAtIndex((int)kKeyframeMove);
103
                        cActionArray->addObject(actionFrame);
104
                }
105

    
106
                bool existScale = DICTOOL->checkObjectExist_json(actionFrameDic,"scalex");
107
                if (existScale)
108
                {
109
                        float scaleX = DICTOOL->getFloatValue_json(actionFrameDic, "scalex");
110
                        float scaleY = DICTOOL->getFloatValue_json(actionFrameDic, "scaley");
111
                        ActionScaleFrame* actionFrame = new ActionScaleFrame();
112
                        actionFrame->setFrameIndex(frameInex);
113
                        actionFrame->setScaleX(scaleX);
114
                        actionFrame->setScaleY(scaleY);
115
                        CCArray* cActionArray = (CCArray*)m_FrameArray->objectAtIndex((int)kKeyframeScale);
116
                        cActionArray->addObject(actionFrame);
117
                }
118

    
119
                bool existRotation = DICTOOL->checkObjectExist_json(actionFrameDic,"rotation");
120
                if (existRotation)
121
                {
122
                        float rotation = DICTOOL->getFloatValue_json(actionFrameDic, "rotation");
123
                        ActionRotationFrame* actionFrame = new ActionRotationFrame();
124
                        actionFrame->setFrameIndex(frameInex);
125
                        actionFrame->setRotation(rotation);
126
                        CCArray* cActionArray = (CCArray*)m_FrameArray->objectAtIndex((int)kKeyframeRotate);
127
                        cActionArray->addObject(actionFrame);
128
                }
129

    
130
                bool existOpacity = DICTOOL->checkObjectExist_json(actionFrameDic,"opacity");
131
                if (existOpacity)
132
                {
133
                        int opacity = DICTOOL->getIntValue_json(actionFrameDic, "opacity");
134
                        ActionFadeFrame* actionFrame = new ActionFadeFrame();
135
                        actionFrame->setFrameIndex(frameInex);
136
                        actionFrame->setOpacity(opacity);
137
                        CCArray* cActionArray = (CCArray*)m_FrameArray->objectAtIndex((int)kKeyframeFade);
138
                        cActionArray->addObject(actionFrame);
139
                }
140

    
141
                bool existColor = DICTOOL->checkObjectExist_json(actionFrameDic,"colorr");
142
                if (existColor)
143
                {
144
                        int colorR = DICTOOL->getIntValue_json(actionFrameDic, "colorr");
145
                        int colorG = DICTOOL->getIntValue_json(actionFrameDic, "colorg");
146
                        int colorB = DICTOOL->getIntValue_json(actionFrameDic, "colorb");
147
                        ActionTintFrame* actionFrame = new ActionTintFrame();
148
                        actionFrame->setFrameIndex(frameInex);
149
                        actionFrame->setColor(ccc3(colorR,colorG,colorB));
150
                        CCArray* cActionArray = (CCArray*)m_FrameArray->objectAtIndex((int)kKeyframeTint);
151
                        cActionArray->addObject(actionFrame);
152
                }
153

    
154
                CC_SAFE_DELETE(actionFrameDic);
155
        }
156
        initActionNodeFromRoot(root);
157
}
158

    
159
void ActionNode::initActionNodeFromRoot(CCObject* root)
160
{        
161
        CCNode* rootNode = dynamic_cast<CCNode*>(root);
162
        if (rootNode != NULL)
163
        {
164
                CCLog("Need a definition of <initActionNodeFromRoot> for gameObject");
165
        }
166
        else
167
        {
168
                UIWidget* rootWidget = dynamic_cast<UIWidget*>(root);
169
                if (rootWidget != NULL)
170
                {
171
                        UIWidget* widget = UIHelper::seekActionWidgetByActionTag(rootWidget, getActionTag());
172
                        if (widget != NULL)
173
                        {
174
                                setObject(widget);
175
                        }
176
                }
177
        }
178
}
179

    
180
void ActionNode::setUnitTime(float fTime)
181
{
182
        m_fUnitTime = fTime;
183
        this->refreshActionProperty();
184
}
185

    
186
float ActionNode::getUnitTime()
187
{
188
        return m_fUnitTime;
189
}
190

    
191
void ActionNode::setActionTag(int tag)
192
{
193
        m_ActionTag = tag;
194
}
195

    
196
int ActionNode::getActionTag()
197
{
198
        return m_ActionTag;
199
}
200

    
201
void ActionNode::setObject(CCObject* node)
202
{
203
        m_Object = node;
204
}
205

    
206
CCObject* ActionNode::getObject()
207
{
208
        return m_Object;
209
}
210

    
211
CCNode* ActionNode::getActionNode()
212
{
213
        CCNode* cNode = dynamic_cast<CCNode*>(m_Object);
214
        if (cNode != NULL)
215
        {
216
                return cNode;
217
        }
218
        else
219
        {
220
                UIWidget* rootWidget = dynamic_cast<UIWidget*>(m_Object);
221
                if (rootWidget != NULL)
222
                {
223
                        return rootWidget->getRenderer();
224
                }
225
        }
226
        return NULL;
227
}
228

    
229
void ActionNode::insertFrame(int index, ActionFrame* frame)
230
{
231
        if (frame == NULL)
232
        {
233
                return;
234
        }
235
        int frameType = frame->getFrameType();
236
        CCArray* cArray = (CCArray*)m_FrameArray->objectAtIndex(frameType);
237
        if (cArray == NULL)
238
        {
239
                return;
240
        }        
241
        cArray->insertObject(frame,index);
242
}
243

    
244
void ActionNode::addFrame(ActionFrame* frame)
245
{
246
        if (frame == NULL)
247
        {
248
                return;
249
        }
250
        int frameType = frame->getFrameType();
251
        CCArray* cArray = (CCArray*)m_FrameArray->objectAtIndex(frameType);
252
        if (cArray == NULL)
253
        {
254
                return;
255
        }
256
        cArray->addObject(frame);
257
}
258

    
259
void ActionNode::deleteFrame(ActionFrame* frame)
260
{
261
        if (frame == NULL)
262
        {
263
                return;
264
        }
265
        int frameType = frame->getFrameType();
266
        CCArray* cArray = (CCArray*)m_FrameArray->objectAtIndex(frameType);
267
        if (cArray == NULL)
268
        { 
269
                return;
270
        }
271
        cArray->removeObject(frame);
272
}
273

    
274
void ActionNode::clearAllFrame()
275
{
276
        for (int i = 0; i < frameArrayNum; i++)
277
        {
278
                m_FrameArray[i].removeAllObjects();
279
        }
280
}
281

    
282
CCSpawn * ActionNode::refreshActionProperty()
283
{
284
        if ( m_Object == NULL )
285
        {
286
                return NULL;
287
        }
288
        CCArray* cSpawnArray = CCArray::create();
289
        for (int n = 0; n < frameArrayNum; n++)
290
        {
291
                CCArray* cArray = (CCArray*)(m_FrameArray->objectAtIndex(n));
292
                if (cArray == NULL || cArray->count() <= 0)
293
                {
294
                        continue;
295
                }
296

    
297
                CCArray* cSequenceArray = CCArray::create();
298
                int frameCount = cArray->count();
299
                for (int i = 0; i < frameCount; i++)
300
                {
301
                        ActionFrame* frame = (ActionFrame*)(cArray->objectAtIndex(i));
302
                        if (i == 0)
303
                        {
304
                        }
305
                        else
306
                        {
307
                                ActionFrame* srcFrame = (ActionFrame*)(cArray->objectAtIndex(i-1));
308
                                float duration = (frame->getFrameIndex() - srcFrame->getFrameIndex()) * getUnitTime();
309
                                CCAction* cAction = frame->getAction(duration);
310
                                cSequenceArray->addObject(cAction);
311
                        }
312
                }
313
                CCSequence* cSequence = CCSequence::create(cSequenceArray);
314
                if (cSequence != NULL)
315
                {
316
                        cSpawnArray->addObject(cSequence);
317
                }
318
        }
319

    
320
        if (m_action == NULL)
321
        {
322
                CC_SAFE_RELEASE_NULL(m_actionSpawn);
323
        }
324
        else
325
        {
326
                CC_SAFE_RELEASE_NULL(m_action);
327
        }
328

    
329
        m_actionSpawn = CCSpawn::create(cSpawnArray);
330
        CC_SAFE_RETAIN(m_actionSpawn);
331
        return m_actionSpawn;
332
}
333

    
334
void ActionNode::playAction()
335
{
336
        if ( m_Object == NULL || m_actionSpawn == NULL)
337
        {
338
                return;
339
        }
340

    
341
        if (m_action!=NULL)
342
        {
343
                m_action->release();
344
        }
345

    
346
        m_action = CCSequence::create(m_actionSpawn,NULL);
347
        m_action->retain();
348

    
349
        this->runAction();
350

    
351
}
352

    
353
void ActionNode::runAction()
354
{
355
        CCNode* cNode = this->getActionNode();
356
        if (cNode != NULL && m_action != NULL)
357
        {
358
                cNode->runAction(m_action);
359
        }
360
}
361

    
362
void ActionNode::stopAction()
363
{
364
        CCNode* cNode = this->getActionNode();
365
        if (cNode != NULL && m_action != NULL)
366
        {
367
                cNode->stopAction(m_action);
368
        }
369
}
370

    
371
int ActionNode::getFirstFrameIndex()
372
{
373
        int frameindex = 99999;
374
        bool bFindFrame = false;
375
        for (int n = 0; n < frameArrayNum; n++)
376
        {
377
                CCArray* cArray = (CCArray*)(m_FrameArray->objectAtIndex(n));
378
                if (cArray == NULL || cArray->count() <= 0)
379
                {
380
                        continue;
381
                }
382

    
383
                bFindFrame = true;
384
                ActionFrame* frame = (ActionFrame*)(cArray->objectAtIndex(0));
385
                int iFrameIndex = frame->getFrameIndex();
386

    
387
                if (frameindex > iFrameIndex)
388
                {
389
                        frameindex = iFrameIndex;
390
                }
391
        }
392
        if (!bFindFrame)
393
        {
394
                frameindex = 0;
395
        }
396
        return frameindex;
397
}
398

    
399
int ActionNode::getLastFrameIndex()
400
{
401
        int frameindex = -1;
402
        bool bFindFrame = false;
403
        for (int n = 0; n < frameArrayNum; n++)
404
        {
405
                CCArray* cArray = (CCArray*)(m_FrameArray->objectAtIndex(n));
406
                if (cArray == NULL || cArray->count() <= 0)
407
                {
408
                        continue;
409
                }
410

    
411
                bFindFrame = true;
412
                int lastInex = cArray->count() - 1;
413
                ActionFrame* frame = (ActionFrame*)(cArray->objectAtIndex(lastInex));
414
                int iFrameIndex = frame->getFrameIndex();
415

    
416
                if (frameindex < iFrameIndex)
417
                {
418
                        frameindex = iFrameIndex;
419
                }
420
        }
421
        if (!bFindFrame)
422
        {
423
                frameindex = 0;
424
        }
425
        return frameindex;
426
}
427
bool ActionNode::updateActionToTimeLine(float fTime)
428
{
429
        bool bFindFrame = false;
430

    
431
        ActionFrame* srcFrame = NULL;
432

    
433
        for (int n = 0; n < frameArrayNum; n++)
434
        {
435
                CCArray* cArray = (CCArray*)(m_FrameArray->objectAtIndex(n));
436
                if (cArray == NULL)
437
                {
438
                        continue;
439
                }
440
                int frameCount = cArray->count();
441
                for (int i = 0; i < frameCount; i++)
442
                {
443
                        ActionFrame* frame = (ActionFrame*)(cArray->objectAtIndex(i));
444

    
445
                        if (frame->getFrameIndex()*getUnitTime() == fTime)
446
                        {
447
                                this->easingToFrame(1.0f,1.0f,frame);
448
                                bFindFrame = true;
449
                                break;
450
                        }
451
                        else if (frame->getFrameIndex()*getUnitTime() > fTime)
452
                        {
453
                                if (i == 0)
454
                                {
455
                                        this->easingToFrame(1.0f,1.0f,frame);
456
                                        bFindFrame = false;
457
                                }
458
                                else
459
                                {
460
                                        srcFrame = (ActionFrame*)(cArray->objectAtIndex(i-1));
461
                                        float duration = (frame->getFrameIndex() - srcFrame->getFrameIndex())*getUnitTime();
462
                                        float delaytime = fTime - srcFrame->getFrameIndex()*getUnitTime();
463
                                        this->easingToFrame(duration,1.0f,srcFrame);
464
                                        //float easingTime = ActionFrameEasing::bounceTime(delaytime);
465
                                        this->easingToFrame(duration,delaytime/duration,frame);
466
                                        bFindFrame = true;
467
                                }
468
                                break;
469
                        }
470
                }
471
        }
472
        return bFindFrame;
473
}
474

    
475
void ActionNode::easingToFrame(float duration,float delayTime,ActionFrame* destFrame)
476
{
477
        CCAction* cAction = destFrame->getAction(duration);
478
        CCNode* cNode = this->getActionNode();
479
        if (cAction == NULL || cNode == NULL)
480
        {
481
                return;
482
        }        
483
        cAction->startWithTarget(cNode);
484
        cAction->update(delayTime);
485
}
486

    
487

    
488
bool ActionNode::isActionDoneOnce()
489
{
490
        if (m_action == NULL)
491
        {
492
                return true;
493
        }
494
        return m_action->isDone();
495
}
496
NS_CC_EXT_END