diff options
Diffstat (limited to 'libs/cocos2d/CCActionInterval.m')
-rwxr-xr-x | libs/cocos2d/CCActionInterval.m | 1355 |
1 files changed, 1355 insertions, 0 deletions
diff --git a/libs/cocos2d/CCActionInterval.m b/libs/cocos2d/CCActionInterval.m new file mode 100755 index 0000000..17bef40 --- /dev/null +++ b/libs/cocos2d/CCActionInterval.m | |||
@@ -0,0 +1,1355 @@ | |||
1 | /* | ||
2 | * cocos2d for iPhone: http://www.cocos2d-iphone.org | ||
3 | * | ||
4 | * Copyright (c) 2008-2011 Ricardo Quesada | ||
5 | * Copyright (c) 2011 Zynga Inc. | ||
6 | * | ||
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
8 | * of this software and associated documentation files (the "Software"), to deal | ||
9 | * in the Software without restriction, including without limitation the rights | ||
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
11 | * copies of the Software, and to permit persons to whom the Software is | ||
12 | * furnished to do so, subject to the following conditions: | ||
13 | * | ||
14 | * The above copyright notice and this permission notice shall be included in | ||
15 | * all copies or substantial portions of the Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
23 | * THE SOFTWARE. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | |||
28 | |||
29 | #import "CCActionInterval.h" | ||
30 | #import "CCSprite.h" | ||
31 | #import "CCSpriteFrame.h" | ||
32 | #import "CCAnimation.h" | ||
33 | #import "CCNode.h" | ||
34 | #import "Support/CGPointExtension.h" | ||
35 | |||
36 | // | ||
37 | // IntervalAction | ||
38 | // | ||
39 | #pragma mark - | ||
40 | #pragma mark IntervalAction | ||
41 | @implementation CCActionInterval | ||
42 | |||
43 | @synthesize elapsed = elapsed_; | ||
44 | |||
45 | -(id) init | ||
46 | { | ||
47 | NSAssert(NO, @"IntervalActionInit: Init not supported. Use InitWithDuration"); | ||
48 | [self release]; | ||
49 | return nil; | ||
50 | } | ||
51 | |||
52 | +(id) actionWithDuration: (ccTime) d | ||
53 | { | ||
54 | return [[[self alloc] initWithDuration:d ] autorelease]; | ||
55 | } | ||
56 | |||
57 | -(id) initWithDuration: (ccTime) d | ||
58 | { | ||
59 | if( (self=[super init]) ) { | ||
60 | duration_ = d; | ||
61 | |||
62 | // prevent division by 0 | ||
63 | // This comparison could be in step:, but it might decrease the performance | ||
64 | // by 3% in heavy based action games. | ||
65 | if( duration_ == 0 ) | ||
66 | duration_ = FLT_EPSILON; | ||
67 | elapsed_ = 0; | ||
68 | firstTick_ = YES; | ||
69 | } | ||
70 | return self; | ||
71 | } | ||
72 | |||
73 | -(id) copyWithZone: (NSZone*) zone | ||
74 | { | ||
75 | CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] ]; | ||
76 | return copy; | ||
77 | } | ||
78 | |||
79 | - (BOOL) isDone | ||
80 | { | ||
81 | return (elapsed_ >= duration_); | ||
82 | } | ||
83 | |||
84 | -(void) step: (ccTime) dt | ||
85 | { | ||
86 | if( firstTick_ ) { | ||
87 | firstTick_ = NO; | ||
88 | elapsed_ = 0; | ||
89 | } else | ||
90 | elapsed_ += dt; | ||
91 | |||
92 | [self update: MIN(1, elapsed_/duration_)]; | ||
93 | } | ||
94 | |||
95 | -(void) startWithTarget:(id)aTarget | ||
96 | { | ||
97 | [super startWithTarget:aTarget]; | ||
98 | elapsed_ = 0.0f; | ||
99 | firstTick_ = YES; | ||
100 | } | ||
101 | |||
102 | - (CCActionInterval*) reverse | ||
103 | { | ||
104 | NSAssert(NO, @"CCIntervalAction: reverse not implemented."); | ||
105 | return nil; | ||
106 | } | ||
107 | @end | ||
108 | |||
109 | // | ||
110 | // Sequence | ||
111 | // | ||
112 | #pragma mark - | ||
113 | #pragma mark Sequence | ||
114 | @implementation CCSequence | ||
115 | +(id) actions: (CCFiniteTimeAction*) action1, ... | ||
116 | { | ||
117 | va_list params; | ||
118 | va_start(params,action1); | ||
119 | |||
120 | CCFiniteTimeAction *now; | ||
121 | CCFiniteTimeAction *prev = action1; | ||
122 | |||
123 | while( action1 ) { | ||
124 | now = va_arg(params,CCFiniteTimeAction*); | ||
125 | if ( now ) | ||
126 | prev = [self actionOne: prev two: now]; | ||
127 | else | ||
128 | break; | ||
129 | } | ||
130 | va_end(params); | ||
131 | return prev; | ||
132 | } | ||
133 | |||
134 | +(id) actionsWithArray: (NSArray*) actions | ||
135 | { | ||
136 | CCFiniteTimeAction *prev = [actions objectAtIndex:0]; | ||
137 | |||
138 | for (NSUInteger i = 1; i < [actions count]; i++) | ||
139 | prev = [self actionOne:prev two:[actions objectAtIndex:i]]; | ||
140 | |||
141 | return prev; | ||
142 | } | ||
143 | |||
144 | +(id) actionOne: (CCFiniteTimeAction*) one two: (CCFiniteTimeAction*) two | ||
145 | { | ||
146 | return [[[self alloc] initOne:one two:two ] autorelease]; | ||
147 | } | ||
148 | |||
149 | -(id) initOne: (CCFiniteTimeAction*) one two: (CCFiniteTimeAction*) two | ||
150 | { | ||
151 | NSAssert( one!=nil && two!=nil, @"Sequence: arguments must be non-nil"); | ||
152 | NSAssert( one!=actions_[0] && one!=actions_[1], @"Sequence: re-init using the same parameters is not supported"); | ||
153 | NSAssert( two!=actions_[1] && two!=actions_[0], @"Sequence: re-init using the same parameters is not supported"); | ||
154 | |||
155 | ccTime d = [one duration] + [two duration]; | ||
156 | |||
157 | if( (self=[super initWithDuration: d]) ) { | ||
158 | |||
159 | // XXX: Supports re-init without leaking. Fails if one==one_ || two==two_ | ||
160 | [actions_[0] release]; | ||
161 | [actions_[1] release]; | ||
162 | |||
163 | actions_[0] = [one retain]; | ||
164 | actions_[1] = [two retain]; | ||
165 | } | ||
166 | |||
167 | return self; | ||
168 | } | ||
169 | |||
170 | -(id) copyWithZone: (NSZone*) zone | ||
171 | { | ||
172 | CCAction *copy = [[[self class] allocWithZone:zone] initOne:[[actions_[0] copy] autorelease] two:[[actions_[1] copy] autorelease] ]; | ||
173 | return copy; | ||
174 | } | ||
175 | |||
176 | -(void) dealloc | ||
177 | { | ||
178 | [actions_[0] release]; | ||
179 | [actions_[1] release]; | ||
180 | [super dealloc]; | ||
181 | } | ||
182 | |||
183 | -(void) startWithTarget:(id)aTarget | ||
184 | { | ||
185 | [super startWithTarget:aTarget]; | ||
186 | split_ = [actions_[0] duration] / duration_; | ||
187 | last_ = -1; | ||
188 | } | ||
189 | |||
190 | -(void) stop | ||
191 | { | ||
192 | [actions_[0] stop]; | ||
193 | [actions_[1] stop]; | ||
194 | [super stop]; | ||
195 | } | ||
196 | |||
197 | -(void) update: (ccTime) t | ||
198 | { | ||
199 | int found = 0; | ||
200 | ccTime new_t = 0.0f; | ||
201 | |||
202 | if( t >= split_ ) { | ||
203 | found = 1; | ||
204 | if ( split_ == 1 ) | ||
205 | new_t = 1; | ||
206 | else | ||
207 | new_t = (t-split_) / (1 - split_ ); | ||
208 | } else { | ||
209 | found = 0; | ||
210 | if( split_ != 0 ) | ||
211 | new_t = t / split_; | ||
212 | else | ||
213 | new_t = 1; | ||
214 | } | ||
215 | |||
216 | if (last_ == -1 && found==1) { | ||
217 | [actions_[0] startWithTarget:target_]; | ||
218 | [actions_[0] update:1.0f]; | ||
219 | [actions_[0] stop]; | ||
220 | } | ||
221 | |||
222 | if (last_ != found ) { | ||
223 | if( last_ != -1 ) { | ||
224 | [actions_[last_] update: 1.0f]; | ||
225 | [actions_[last_] stop]; | ||
226 | } | ||
227 | [actions_[found] startWithTarget:target_]; | ||
228 | } | ||
229 | [actions_[found] update: new_t]; | ||
230 | last_ = found; | ||
231 | } | ||
232 | |||
233 | - (CCActionInterval *) reverse | ||
234 | { | ||
235 | return [[self class] actionOne: [actions_[1] reverse] two: [actions_[0] reverse ] ]; | ||
236 | } | ||
237 | @end | ||
238 | |||
239 | // | ||
240 | // Repeat | ||
241 | // | ||
242 | #pragma mark - | ||
243 | #pragma mark CCRepeat | ||
244 | @implementation CCRepeat | ||
245 | @synthesize innerAction=innerAction_; | ||
246 | |||
247 | +(id) actionWithAction:(CCFiniteTimeAction*)action times:(NSUInteger)times | ||
248 | { | ||
249 | return [[[self alloc] initWithAction:action times:times] autorelease]; | ||
250 | } | ||
251 | |||
252 | -(id) initWithAction:(CCFiniteTimeAction*)action times:(NSUInteger)times | ||
253 | { | ||
254 | ccTime d = [action duration] * times; | ||
255 | |||
256 | if( (self=[super initWithDuration: d ]) ) { | ||
257 | times_ = times; | ||
258 | self.innerAction = action; | ||
259 | |||
260 | total_ = 0; | ||
261 | } | ||
262 | return self; | ||
263 | } | ||
264 | |||
265 | -(id) copyWithZone: (NSZone*) zone | ||
266 | { | ||
267 | CCAction *copy = [[[self class] allocWithZone:zone] initWithAction:[[innerAction_ copy] autorelease] times:times_]; | ||
268 | return copy; | ||
269 | } | ||
270 | |||
271 | -(void) dealloc | ||
272 | { | ||
273 | [innerAction_ release]; | ||
274 | [super dealloc]; | ||
275 | } | ||
276 | |||
277 | -(void) startWithTarget:(id)aTarget | ||
278 | { | ||
279 | total_ = 0; | ||
280 | [super startWithTarget:aTarget]; | ||
281 | [innerAction_ startWithTarget:aTarget]; | ||
282 | } | ||
283 | |||
284 | -(void) stop | ||
285 | { | ||
286 | [innerAction_ stop]; | ||
287 | [super stop]; | ||
288 | } | ||
289 | |||
290 | |||
291 | // issue #80. Instead of hooking step:, hook update: since it can be called by any | ||
292 | // container action like Repeat, Sequence, AccelDeccel, etc.. | ||
293 | -(void) update:(ccTime) dt | ||
294 | { | ||
295 | ccTime t = dt * times_; | ||
296 | if( t > total_+1 ) { | ||
297 | [innerAction_ update:1.0f]; | ||
298 | total_++; | ||
299 | [innerAction_ stop]; | ||
300 | [innerAction_ startWithTarget:target_]; | ||
301 | |||
302 | // repeat is over ? | ||
303 | if( total_== times_ ) | ||
304 | // so, set it in the original position | ||
305 | [innerAction_ update:0]; | ||
306 | else { | ||
307 | // no ? start next repeat with the right update | ||
308 | // to prevent jerk (issue #390) | ||
309 | [innerAction_ update: t-total_]; | ||
310 | } | ||
311 | |||
312 | } else { | ||
313 | |||
314 | float r = fmodf(t, 1.0f); | ||
315 | |||
316 | // fix last repeat position | ||
317 | // else it could be 0. | ||
318 | if( dt== 1.0f) { | ||
319 | r = 1.0f; | ||
320 | total_++; // this is the added line | ||
321 | } | ||
322 | [innerAction_ update: MIN(r,1)]; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | -(BOOL) isDone | ||
327 | { | ||
328 | return ( total_ == times_ ); | ||
329 | } | ||
330 | |||
331 | - (CCActionInterval *) reverse | ||
332 | { | ||
333 | return [[self class] actionWithAction:[innerAction_ reverse] times:times_]; | ||
334 | } | ||
335 | @end | ||
336 | |||
337 | // | ||
338 | // Spawn | ||
339 | // | ||
340 | #pragma mark - | ||
341 | #pragma mark Spawn | ||
342 | |||
343 | @implementation CCSpawn | ||
344 | +(id) actions: (CCFiniteTimeAction*) action1, ... | ||
345 | { | ||
346 | va_list params; | ||
347 | va_start(params,action1); | ||
348 | |||
349 | CCFiniteTimeAction *now; | ||
350 | CCFiniteTimeAction *prev = action1; | ||
351 | |||
352 | while( action1 ) { | ||
353 | now = va_arg(params,CCFiniteTimeAction*); | ||
354 | if ( now ) | ||
355 | prev = [self actionOne: prev two: now]; | ||
356 | else | ||
357 | break; | ||
358 | } | ||
359 | va_end(params); | ||
360 | return prev; | ||
361 | } | ||
362 | |||
363 | +(id) actionsWithArray: (NSArray*) actions | ||
364 | { | ||
365 | CCFiniteTimeAction *prev = [actions objectAtIndex:0]; | ||
366 | |||
367 | for (NSUInteger i = 1; i < [actions count]; i++) | ||
368 | prev = [self actionOne:prev two:[actions objectAtIndex:i]]; | ||
369 | |||
370 | return prev; | ||
371 | } | ||
372 | |||
373 | +(id) actionOne: (CCFiniteTimeAction*) one two: (CCFiniteTimeAction*) two | ||
374 | { | ||
375 | return [[[self alloc] initOne:one two:two ] autorelease]; | ||
376 | } | ||
377 | |||
378 | -(id) initOne: (CCFiniteTimeAction*) one two: (CCFiniteTimeAction*) two | ||
379 | { | ||
380 | NSAssert( one!=nil && two!=nil, @"Spawn: arguments must be non-nil"); | ||
381 | NSAssert( one!=one_ && one!=two_, @"Spawn: reinit using same parameters is not supported"); | ||
382 | NSAssert( two!=two_ && two!=one_, @"Spawn: reinit using same parameters is not supported"); | ||
383 | |||
384 | ccTime d1 = [one duration]; | ||
385 | ccTime d2 = [two duration]; | ||
386 | |||
387 | if( (self=[super initWithDuration: MAX(d1,d2)] ) ) { | ||
388 | |||
389 | // XXX: Supports re-init without leaking. Fails if one==one_ || two==two_ | ||
390 | [one_ release]; | ||
391 | [two_ release]; | ||
392 | |||
393 | one_ = one; | ||
394 | two_ = two; | ||
395 | |||
396 | if( d1 > d2 ) | ||
397 | two_ = [CCSequence actionOne:two two:[CCDelayTime actionWithDuration: (d1-d2)] ]; | ||
398 | else if( d1 < d2) | ||
399 | one_ = [CCSequence actionOne:one two: [CCDelayTime actionWithDuration: (d2-d1)] ]; | ||
400 | |||
401 | [one_ retain]; | ||
402 | [two_ retain]; | ||
403 | } | ||
404 | return self; | ||
405 | } | ||
406 | |||
407 | -(id) copyWithZone: (NSZone*) zone | ||
408 | { | ||
409 | CCAction *copy = [[[self class] allocWithZone: zone] initOne: [[one_ copy] autorelease] two: [[two_ copy] autorelease] ]; | ||
410 | return copy; | ||
411 | } | ||
412 | |||
413 | -(void) dealloc | ||
414 | { | ||
415 | [one_ release]; | ||
416 | [two_ release]; | ||
417 | [super dealloc]; | ||
418 | } | ||
419 | |||
420 | -(void) startWithTarget:(id)aTarget | ||
421 | { | ||
422 | [super startWithTarget:aTarget]; | ||
423 | [one_ startWithTarget:target_]; | ||
424 | [two_ startWithTarget:target_]; | ||
425 | } | ||
426 | |||
427 | -(void) stop | ||
428 | { | ||
429 | [one_ stop]; | ||
430 | [two_ stop]; | ||
431 | [super stop]; | ||
432 | } | ||
433 | |||
434 | -(void) update: (ccTime) t | ||
435 | { | ||
436 | [one_ update:t]; | ||
437 | [two_ update:t]; | ||
438 | } | ||
439 | |||
440 | - (CCActionInterval *) reverse | ||
441 | { | ||
442 | return [[self class] actionOne: [one_ reverse] two: [two_ reverse ] ]; | ||
443 | } | ||
444 | @end | ||
445 | |||
446 | // | ||
447 | // RotateTo | ||
448 | // | ||
449 | #pragma mark - | ||
450 | #pragma mark RotateTo | ||
451 | |||
452 | @implementation CCRotateTo | ||
453 | +(id) actionWithDuration: (ccTime) t angle:(float) a | ||
454 | { | ||
455 | return [[[self alloc] initWithDuration:t angle:a ] autorelease]; | ||
456 | } | ||
457 | |||
458 | -(id) initWithDuration: (ccTime) t angle:(float) a | ||
459 | { | ||
460 | if( (self=[super initWithDuration: t]) ) | ||
461 | dstAngle_ = a; | ||
462 | |||
463 | return self; | ||
464 | } | ||
465 | |||
466 | -(id) copyWithZone: (NSZone*) zone | ||
467 | { | ||
468 | CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration:[self duration] angle:dstAngle_]; | ||
469 | return copy; | ||
470 | } | ||
471 | |||
472 | -(void) startWithTarget:(CCNode *)aTarget | ||
473 | { | ||
474 | [super startWithTarget:aTarget]; | ||
475 | |||
476 | startAngle_ = [target_ rotation]; | ||
477 | if (startAngle_ > 0) | ||
478 | startAngle_ = fmodf(startAngle_, 360.0f); | ||
479 | else | ||
480 | startAngle_ = fmodf(startAngle_, -360.0f); | ||
481 | |||
482 | diffAngle_ =dstAngle_ - startAngle_; | ||
483 | if (diffAngle_ > 180) | ||
484 | diffAngle_ -= 360; | ||
485 | if (diffAngle_ < -180) | ||
486 | diffAngle_ += 360; | ||
487 | } | ||
488 | -(void) update: (ccTime) t | ||
489 | { | ||
490 | [target_ setRotation: startAngle_ + diffAngle_ * t]; | ||
491 | } | ||
492 | @end | ||
493 | |||
494 | |||
495 | // | ||
496 | // RotateBy | ||
497 | // | ||
498 | #pragma mark - | ||
499 | #pragma mark RotateBy | ||
500 | |||
501 | @implementation CCRotateBy | ||
502 | +(id) actionWithDuration: (ccTime) t angle:(float) a | ||
503 | { | ||
504 | return [[[self alloc] initWithDuration:t angle:a ] autorelease]; | ||
505 | } | ||
506 | |||
507 | -(id) initWithDuration: (ccTime) t angle:(float) a | ||
508 | { | ||
509 | if( (self=[super initWithDuration: t]) ) | ||
510 | angle_ = a; | ||
511 | |||
512 | return self; | ||
513 | } | ||
514 | |||
515 | -(id) copyWithZone: (NSZone*) zone | ||
516 | { | ||
517 | CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] angle: angle_]; | ||
518 | return copy; | ||
519 | } | ||
520 | |||
521 | -(void) startWithTarget:(id)aTarget | ||
522 | { | ||
523 | [super startWithTarget:aTarget]; | ||
524 | startAngle_ = [target_ rotation]; | ||
525 | } | ||
526 | |||
527 | -(void) update: (ccTime) t | ||
528 | { | ||
529 | // XXX: shall I add % 360 | ||
530 | [target_ setRotation: (startAngle_ +angle_ * t )]; | ||
531 | } | ||
532 | |||
533 | -(CCActionInterval*) reverse | ||
534 | { | ||
535 | return [[self class] actionWithDuration:duration_ angle:-angle_]; | ||
536 | } | ||
537 | |||
538 | @end | ||
539 | |||
540 | // | ||
541 | // MoveTo | ||
542 | // | ||
543 | #pragma mark - | ||
544 | #pragma mark MoveTo | ||
545 | |||
546 | @implementation CCMoveTo | ||
547 | +(id) actionWithDuration: (ccTime) t position: (CGPoint) p | ||
548 | { | ||
549 | return [[[self alloc] initWithDuration:t position:p ] autorelease]; | ||
550 | } | ||
551 | |||
552 | -(id) initWithDuration: (ccTime) t position: (CGPoint) p | ||
553 | { | ||
554 | if( (self=[super initWithDuration: t]) ) | ||
555 | endPosition_ = p; | ||
556 | |||
557 | return self; | ||
558 | } | ||
559 | |||
560 | -(id) copyWithZone: (NSZone*) zone | ||
561 | { | ||
562 | CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] position: endPosition_]; | ||
563 | return copy; | ||
564 | } | ||
565 | |||
566 | -(void) startWithTarget:(CCNode *)aTarget | ||
567 | { | ||
568 | [super startWithTarget:aTarget]; | ||
569 | startPosition_ = [(CCNode*)target_ position]; | ||
570 | delta_ = ccpSub( endPosition_, startPosition_ ); | ||
571 | } | ||
572 | |||
573 | -(void) update: (ccTime) t | ||
574 | { | ||
575 | [target_ setPosition: ccp( (startPosition_.x + delta_.x * t ), (startPosition_.y + delta_.y * t ) )]; | ||
576 | } | ||
577 | @end | ||
578 | |||
579 | // | ||
580 | // MoveBy | ||
581 | // | ||
582 | #pragma mark - | ||
583 | #pragma mark MoveBy | ||
584 | |||
585 | @implementation CCMoveBy | ||
586 | +(id) actionWithDuration: (ccTime) t position: (CGPoint) p | ||
587 | { | ||
588 | return [[[self alloc] initWithDuration:t position:p ] autorelease]; | ||
589 | } | ||
590 | |||
591 | -(id) initWithDuration: (ccTime) t position: (CGPoint) p | ||
592 | { | ||
593 | if( (self=[super initWithDuration: t]) ) | ||
594 | delta_ = p; | ||
595 | |||
596 | return self; | ||
597 | } | ||
598 | |||
599 | -(id) copyWithZone: (NSZone*) zone | ||
600 | { | ||
601 | CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] position: delta_]; | ||
602 | return copy; | ||
603 | } | ||
604 | |||
605 | -(void) startWithTarget:(CCNode *)aTarget | ||
606 | { | ||
607 | CGPoint dTmp = delta_; | ||
608 | [super startWithTarget:aTarget]; | ||
609 | delta_ = dTmp; | ||
610 | } | ||
611 | |||
612 | -(CCActionInterval*) reverse | ||
613 | { | ||
614 | return [[self class] actionWithDuration:duration_ position:ccp( -delta_.x, -delta_.y)]; | ||
615 | } | ||
616 | @end | ||
617 | |||
618 | |||
619 | // | ||
620 | // SkewTo | ||
621 | // | ||
622 | #pragma mark - | ||
623 | #pragma mark SkewTo | ||
624 | |||
625 | @implementation CCSkewTo | ||
626 | +(id) actionWithDuration:(ccTime)t skewX:(float)sx skewY:(float)sy | ||
627 | { | ||
628 | return [[[self alloc] initWithDuration: t skewX:sx skewY:sy] autorelease]; | ||
629 | } | ||
630 | |||
631 | -(id) initWithDuration:(ccTime)t skewX:(float)sx skewY:(float)sy | ||
632 | { | ||
633 | if( (self=[super initWithDuration:t]) ) { | ||
634 | endSkewX_ = sx; | ||
635 | endSkewY_ = sy; | ||
636 | } | ||
637 | return self; | ||
638 | } | ||
639 | |||
640 | -(id) copyWithZone: (NSZone*) zone | ||
641 | { | ||
642 | CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration:[self duration] skewX:endSkewX_ skewY:endSkewY_]; | ||
643 | return copy; | ||
644 | } | ||
645 | |||
646 | -(void) startWithTarget:(CCNode *)aTarget | ||
647 | { | ||
648 | [super startWithTarget:aTarget]; | ||
649 | |||
650 | startSkewX_ = [target_ skewX]; | ||
651 | |||
652 | if (startSkewX_ > 0) | ||
653 | startSkewX_ = fmodf(startSkewX_, 180.0f); | ||
654 | else | ||
655 | startSkewX_ = fmodf(startSkewX_, -180.0f); | ||
656 | |||
657 | deltaX_ = endSkewX_ - startSkewX_; | ||
658 | |||
659 | if ( deltaX_ > 180 ) { | ||
660 | deltaX_ -= 360; | ||
661 | } | ||
662 | if ( deltaX_ < -180 ) { | ||
663 | deltaX_ += 360; | ||
664 | } | ||
665 | |||
666 | startSkewY_ = [target_ skewY]; | ||
667 | |||
668 | if (startSkewY_ > 0) | ||
669 | startSkewY_ = fmodf(startSkewY_, 360.0f); | ||
670 | else | ||
671 | startSkewY_ = fmodf(startSkewY_, -360.0f); | ||
672 | |||
673 | deltaY_ = endSkewY_ - startSkewY_; | ||
674 | |||
675 | if ( deltaY_ > 180 ) { | ||
676 | deltaY_ -= 360; | ||
677 | } | ||
678 | if ( deltaY_ < -180 ) { | ||
679 | deltaY_ += 360; | ||
680 | } | ||
681 | } | ||
682 | |||
683 | -(void) update: (ccTime) t | ||
684 | { | ||
685 | [target_ setSkewX: (startSkewX_ + deltaX_ * t ) ]; | ||
686 | [target_ setSkewY: (startSkewY_ + deltaY_ * t ) ]; | ||
687 | } | ||
688 | |||
689 | @end | ||
690 | |||
691 | // | ||
692 | // CCSkewBy | ||
693 | // | ||
694 | @implementation CCSkewBy | ||
695 | |||
696 | -(id) initWithDuration:(ccTime)t skewX:(float)deltaSkewX skewY:(float)deltaSkewY | ||
697 | { | ||
698 | if( (self=[super initWithDuration:t skewX:deltaSkewX skewY:deltaSkewY]) ) { | ||
699 | skewX_ = deltaSkewX; | ||
700 | skewY_ = deltaSkewY; | ||
701 | } | ||
702 | return self; | ||
703 | } | ||
704 | |||
705 | -(void) startWithTarget:(CCNode *)aTarget | ||
706 | { | ||
707 | [super startWithTarget:aTarget]; | ||
708 | deltaX_ = skewX_; | ||
709 | deltaY_ = skewY_; | ||
710 | endSkewX_ = startSkewX_ + deltaX_; | ||
711 | endSkewY_ = startSkewY_ + deltaY_; | ||
712 | } | ||
713 | |||
714 | -(CCActionInterval*) reverse | ||
715 | { | ||
716 | return [[self class] actionWithDuration:duration_ skewX:-skewX_ skewY:-skewY_]; | ||
717 | } | ||
718 | @end | ||
719 | |||
720 | |||
721 | // | ||
722 | // JumpBy | ||
723 | // | ||
724 | #pragma mark - | ||
725 | #pragma mark JumpBy | ||
726 | |||
727 | @implementation CCJumpBy | ||
728 | +(id) actionWithDuration: (ccTime) t position: (CGPoint) pos height: (ccTime) h jumps:(NSUInteger)j | ||
729 | { | ||
730 | return [[[self alloc] initWithDuration: t position: pos height: h jumps:j] autorelease]; | ||
731 | } | ||
732 | |||
733 | -(id) initWithDuration: (ccTime) t position: (CGPoint) pos height: (ccTime) h jumps:(NSUInteger)j | ||
734 | { | ||
735 | if( (self=[super initWithDuration:t]) ) { | ||
736 | delta_ = pos; | ||
737 | height_ = h; | ||
738 | jumps_ = j; | ||
739 | } | ||
740 | return self; | ||
741 | } | ||
742 | |||
743 | -(id) copyWithZone: (NSZone*) zone | ||
744 | { | ||
745 | CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration:[self duration] position:delta_ height:height_ jumps:jumps_]; | ||
746 | return copy; | ||
747 | } | ||
748 | |||
749 | -(void) startWithTarget:(id)aTarget | ||
750 | { | ||
751 | [super startWithTarget:aTarget]; | ||
752 | startPosition_ = [(CCNode*)target_ position]; | ||
753 | } | ||
754 | |||
755 | -(void) update: (ccTime) t | ||
756 | { | ||
757 | // Sin jump. Less realistic | ||
758 | // ccTime y = height * fabsf( sinf(t * (CGFloat)M_PI * jumps ) ); | ||
759 | // y += delta.y * t; | ||
760 | // ccTime x = delta.x * t; | ||
761 | // [target setPosition: ccp( startPosition.x + x, startPosition.y + y )]; | ||
762 | |||
763 | // parabolic jump (since v0.8.2) | ||
764 | ccTime frac = fmodf( t * jumps_, 1.0f ); | ||
765 | ccTime y = height_ * 4 * frac * (1 - frac); | ||
766 | y += delta_.y * t; | ||
767 | ccTime x = delta_.x * t; | ||
768 | [target_ setPosition: ccp( startPosition_.x + x, startPosition_.y + y )]; | ||
769 | |||
770 | } | ||
771 | |||
772 | -(CCActionInterval*) reverse | ||
773 | { | ||
774 | return [[self class] actionWithDuration:duration_ position: ccp(-delta_.x,-delta_.y) height:height_ jumps:jumps_]; | ||
775 | } | ||
776 | @end | ||
777 | |||
778 | // | ||
779 | // JumpTo | ||
780 | // | ||
781 | #pragma mark - | ||
782 | #pragma mark JumpTo | ||
783 | |||
784 | @implementation CCJumpTo | ||
785 | -(void) startWithTarget:(CCNode *)aTarget | ||
786 | { | ||
787 | [super startWithTarget:aTarget]; | ||
788 | delta_ = ccp( delta_.x - startPosition_.x, delta_.y - startPosition_.y ); | ||
789 | } | ||
790 | @end | ||
791 | |||
792 | |||
793 | #pragma mark - | ||
794 | #pragma mark BezierBy | ||
795 | |||
796 | // Bezier cubic formula: | ||
797 | // ((1 - t) + t)3 = 1 | ||
798 | // Expands to… | ||
799 | // (1 - t)3 + 3t(1-t)2 + 3t2(1 - t) + t3 = 1 | ||
800 | static inline float bezierat( float a, float b, float c, float d, ccTime t ) | ||
801 | { | ||
802 | return (powf(1-t,3) * a + | ||
803 | 3*t*(powf(1-t,2))*b + | ||
804 | 3*powf(t,2)*(1-t)*c + | ||
805 | powf(t,3)*d ); | ||
806 | } | ||
807 | |||
808 | // | ||
809 | // BezierBy | ||
810 | // | ||
811 | @implementation CCBezierBy | ||
812 | +(id) actionWithDuration: (ccTime) t bezier:(ccBezierConfig) c | ||
813 | { | ||
814 | return [[[self alloc] initWithDuration:t bezier:c ] autorelease]; | ||
815 | } | ||
816 | |||
817 | -(id) initWithDuration: (ccTime) t bezier:(ccBezierConfig) c | ||
818 | { | ||
819 | if( (self=[super initWithDuration: t]) ) { | ||
820 | config_ = c; | ||
821 | } | ||
822 | return self; | ||
823 | } | ||
824 | |||
825 | -(id) copyWithZone: (NSZone*) zone | ||
826 | { | ||
827 | CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration:[self duration] bezier:config_]; | ||
828 | return copy; | ||
829 | } | ||
830 | |||
831 | -(void) startWithTarget:(id)aTarget | ||
832 | { | ||
833 | [super startWithTarget:aTarget]; | ||
834 | startPosition_ = [(CCNode*)target_ position]; | ||
835 | } | ||
836 | |||
837 | -(void) update: (ccTime) t | ||
838 | { | ||
839 | float xa = 0; | ||
840 | float xb = config_.controlPoint_1.x; | ||
841 | float xc = config_.controlPoint_2.x; | ||
842 | float xd = config_.endPosition.x; | ||
843 | |||
844 | float ya = 0; | ||
845 | float yb = config_.controlPoint_1.y; | ||
846 | float yc = config_.controlPoint_2.y; | ||
847 | float yd = config_.endPosition.y; | ||
848 | |||
849 | float x = bezierat(xa, xb, xc, xd, t); | ||
850 | float y = bezierat(ya, yb, yc, yd, t); | ||
851 | [target_ setPosition: ccpAdd( startPosition_, ccp(x,y))]; | ||
852 | } | ||
853 | |||
854 | - (CCActionInterval*) reverse | ||
855 | { | ||
856 | ccBezierConfig r; | ||
857 | |||
858 | r.endPosition = ccpNeg(config_.endPosition); | ||
859 | r.controlPoint_1 = ccpAdd(config_.controlPoint_2, ccpNeg(config_.endPosition)); | ||
860 | r.controlPoint_2 = ccpAdd(config_.controlPoint_1, ccpNeg(config_.endPosition)); | ||
861 | |||
862 | CCBezierBy *action = [[self class] actionWithDuration:[self duration] bezier:r]; | ||
863 | return action; | ||
864 | } | ||
865 | @end | ||
866 | |||
867 | // | ||
868 | // BezierTo | ||
869 | // | ||
870 | #pragma mark - | ||
871 | #pragma mark BezierTo | ||
872 | @implementation CCBezierTo | ||
873 | -(void) startWithTarget:(id)aTarget | ||
874 | { | ||
875 | [super startWithTarget:aTarget]; | ||
876 | config_.controlPoint_1 = ccpSub(config_.controlPoint_1, startPosition_); | ||
877 | config_.controlPoint_2 = ccpSub(config_.controlPoint_2, startPosition_); | ||
878 | config_.endPosition = ccpSub(config_.endPosition, startPosition_); | ||
879 | } | ||
880 | @end | ||
881 | |||
882 | |||
883 | // | ||
884 | // ScaleTo | ||
885 | // | ||
886 | #pragma mark - | ||
887 | #pragma mark ScaleTo | ||
888 | @implementation CCScaleTo | ||
889 | +(id) actionWithDuration: (ccTime) t scale:(float) s | ||
890 | { | ||
891 | return [[[self alloc] initWithDuration: t scale:s] autorelease]; | ||
892 | } | ||
893 | |||
894 | -(id) initWithDuration: (ccTime) t scale:(float) s | ||
895 | { | ||
896 | if( (self=[super initWithDuration: t]) ) { | ||
897 | endScaleX_ = s; | ||
898 | endScaleY_ = s; | ||
899 | } | ||
900 | return self; | ||
901 | } | ||
902 | |||
903 | +(id) actionWithDuration: (ccTime) t scaleX:(float)sx scaleY:(float)sy | ||
904 | { | ||
905 | return [[[self alloc] initWithDuration: t scaleX:sx scaleY:sy] autorelease]; | ||
906 | } | ||
907 | |||
908 | -(id) initWithDuration: (ccTime) t scaleX:(float)sx scaleY:(float)sy | ||
909 | { | ||
910 | if( (self=[super initWithDuration: t]) ) { | ||
911 | endScaleX_ = sx; | ||
912 | endScaleY_ = sy; | ||
913 | } | ||
914 | return self; | ||
915 | } | ||
916 | |||
917 | -(id) copyWithZone: (NSZone*) zone | ||
918 | { | ||
919 | CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration:[self duration] scaleX:endScaleX_ scaleY:endScaleY_]; | ||
920 | return copy; | ||
921 | } | ||
922 | |||
923 | -(void) startWithTarget:(CCNode *)aTarget | ||
924 | { | ||
925 | [super startWithTarget:aTarget]; | ||
926 | startScaleX_ = [target_ scaleX]; | ||
927 | startScaleY_ = [target_ scaleY]; | ||
928 | deltaX_ = endScaleX_ - startScaleX_; | ||
929 | deltaY_ = endScaleY_ - startScaleY_; | ||
930 | } | ||
931 | |||
932 | -(void) update: (ccTime) t | ||
933 | { | ||
934 | [target_ setScaleX: (startScaleX_ + deltaX_ * t ) ]; | ||
935 | [target_ setScaleY: (startScaleY_ + deltaY_ * t ) ]; | ||
936 | } | ||
937 | @end | ||
938 | |||
939 | // | ||
940 | // ScaleBy | ||
941 | // | ||
942 | #pragma mark - | ||
943 | #pragma mark ScaleBy | ||
944 | @implementation CCScaleBy | ||
945 | -(void) startWithTarget:(CCNode *)aTarget | ||
946 | { | ||
947 | [super startWithTarget:aTarget]; | ||
948 | deltaX_ = startScaleX_ * endScaleX_ - startScaleX_; | ||
949 | deltaY_ = startScaleY_ * endScaleY_ - startScaleY_; | ||
950 | } | ||
951 | |||
952 | -(CCActionInterval*) reverse | ||
953 | { | ||
954 | return [[self class] actionWithDuration:duration_ scaleX:1/endScaleX_ scaleY:1/endScaleY_]; | ||
955 | } | ||
956 | @end | ||
957 | |||
958 | // | ||
959 | // Blink | ||
960 | // | ||
961 | #pragma mark - | ||
962 | #pragma mark Blink | ||
963 | @implementation CCBlink | ||
964 | +(id) actionWithDuration: (ccTime) t blinks: (NSUInteger) b | ||
965 | { | ||
966 | return [[[ self alloc] initWithDuration: t blinks: b] autorelease]; | ||
967 | } | ||
968 | |||
969 | -(id) initWithDuration: (ccTime) t blinks: (NSUInteger) b | ||
970 | { | ||
971 | if( (self=[super initWithDuration: t] ) ) | ||
972 | times_ = b; | ||
973 | |||
974 | return self; | ||
975 | } | ||
976 | |||
977 | -(id) copyWithZone: (NSZone*) zone | ||
978 | { | ||
979 | CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] blinks: times_]; | ||
980 | return copy; | ||
981 | } | ||
982 | |||
983 | -(void) update: (ccTime) t | ||
984 | { | ||
985 | if( ! [self isDone] ) { | ||
986 | ccTime slice = 1.0f / times_; | ||
987 | ccTime m = fmodf(t, slice); | ||
988 | [target_ setVisible: (m > slice/2) ? YES : NO]; | ||
989 | } | ||
990 | } | ||
991 | |||
992 | -(CCActionInterval*) reverse | ||
993 | { | ||
994 | // return 'self' | ||
995 | return [[self class] actionWithDuration:duration_ blinks: times_]; | ||
996 | } | ||
997 | @end | ||
998 | |||
999 | // | ||
1000 | // FadeIn | ||
1001 | // | ||
1002 | #pragma mark - | ||
1003 | #pragma mark FadeIn | ||
1004 | @implementation CCFadeIn | ||
1005 | -(void) update: (ccTime) t | ||
1006 | { | ||
1007 | [(id<CCRGBAProtocol>) target_ setOpacity: 255 *t]; | ||
1008 | } | ||
1009 | |||
1010 | -(CCActionInterval*) reverse | ||
1011 | { | ||
1012 | return [CCFadeOut actionWithDuration:duration_]; | ||
1013 | } | ||
1014 | @end | ||
1015 | |||
1016 | // | ||
1017 | // FadeOut | ||
1018 | // | ||
1019 | #pragma mark - | ||
1020 | #pragma mark FadeOut | ||
1021 | @implementation CCFadeOut | ||
1022 | -(void) update: (ccTime) t | ||
1023 | { | ||
1024 | [(id<CCRGBAProtocol>) target_ setOpacity: 255 *(1-t)]; | ||
1025 | } | ||
1026 | |||
1027 | -(CCActionInterval*) reverse | ||
1028 | { | ||
1029 | return [CCFadeIn actionWithDuration:duration_]; | ||
1030 | } | ||
1031 | @end | ||
1032 | |||
1033 | // | ||
1034 | // FadeTo | ||
1035 | // | ||
1036 | #pragma mark - | ||
1037 | #pragma mark FadeTo | ||
1038 | @implementation CCFadeTo | ||
1039 | +(id) actionWithDuration: (ccTime) t opacity: (GLubyte) o | ||
1040 | { | ||
1041 | return [[[ self alloc] initWithDuration: t opacity: o] autorelease]; | ||
1042 | } | ||
1043 | |||
1044 | -(id) initWithDuration: (ccTime) t opacity: (GLubyte) o | ||
1045 | { | ||
1046 | if( (self=[super initWithDuration: t] ) ) | ||
1047 | toOpacity_ = o; | ||
1048 | |||
1049 | return self; | ||
1050 | } | ||
1051 | |||
1052 | -(id) copyWithZone: (NSZone*) zone | ||
1053 | { | ||
1054 | CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration:[self duration] opacity:toOpacity_]; | ||
1055 | return copy; | ||
1056 | } | ||
1057 | |||
1058 | -(void) startWithTarget:(CCNode *)aTarget | ||
1059 | { | ||
1060 | [super startWithTarget:aTarget]; | ||
1061 | fromOpacity_ = [(id<CCRGBAProtocol>)target_ opacity]; | ||
1062 | } | ||
1063 | |||
1064 | -(void) update: (ccTime) t | ||
1065 | { | ||
1066 | [(id<CCRGBAProtocol>)target_ setOpacity:fromOpacity_ + ( toOpacity_ - fromOpacity_ ) * t]; | ||
1067 | } | ||
1068 | @end | ||
1069 | |||
1070 | // | ||
1071 | // TintTo | ||
1072 | // | ||
1073 | #pragma mark - | ||
1074 | #pragma mark TintTo | ||
1075 | @implementation CCTintTo | ||
1076 | +(id) actionWithDuration:(ccTime)t red:(GLubyte)r green:(GLubyte)g blue:(GLubyte)b | ||
1077 | { | ||
1078 | return [[(CCTintTo*)[ self alloc] initWithDuration:t red:r green:g blue:b] autorelease]; | ||
1079 | } | ||
1080 | |||
1081 | -(id) initWithDuration: (ccTime) t red:(GLubyte)r green:(GLubyte)g blue:(GLubyte)b | ||
1082 | { | ||
1083 | if( (self=[super initWithDuration:t] ) ) | ||
1084 | to_ = ccc3(r,g,b); | ||
1085 | |||
1086 | return self; | ||
1087 | } | ||
1088 | |||
1089 | -(id) copyWithZone: (NSZone*) zone | ||
1090 | { | ||
1091 | CCAction *copy = [(CCTintTo*)[[self class] allocWithZone: zone] initWithDuration:[self duration] red:to_.r green:to_.g blue:to_.b]; | ||
1092 | return copy; | ||
1093 | } | ||
1094 | |||
1095 | -(void) startWithTarget:(id)aTarget | ||
1096 | { | ||
1097 | [super startWithTarget:aTarget]; | ||
1098 | |||
1099 | id<CCRGBAProtocol> tn = (id<CCRGBAProtocol>) target_; | ||
1100 | from_ = [tn color]; | ||
1101 | } | ||
1102 | |||
1103 | -(void) update: (ccTime) t | ||
1104 | { | ||
1105 | id<CCRGBAProtocol> tn = (id<CCRGBAProtocol>) target_; | ||
1106 | [tn setColor:ccc3(from_.r + (to_.r - from_.r) * t, from_.g + (to_.g - from_.g) * t, from_.b + (to_.b - from_.b) * t)]; | ||
1107 | } | ||
1108 | @end | ||
1109 | |||
1110 | // | ||
1111 | // TintBy | ||
1112 | // | ||
1113 | #pragma mark - | ||
1114 | #pragma mark TintBy | ||
1115 | @implementation CCTintBy | ||
1116 | +(id) actionWithDuration:(ccTime)t red:(GLshort)r green:(GLshort)g blue:(GLshort)b | ||
1117 | { | ||
1118 | return [[(CCTintBy*)[ self alloc] initWithDuration:t red:r green:g blue:b] autorelease]; | ||
1119 | } | ||
1120 | |||
1121 | -(id) initWithDuration:(ccTime)t red:(GLshort)r green:(GLshort)g blue:(GLshort)b | ||
1122 | { | ||
1123 | if( (self=[super initWithDuration: t] ) ) { | ||
1124 | deltaR_ = r; | ||
1125 | deltaG_ = g; | ||
1126 | deltaB_ = b; | ||
1127 | } | ||
1128 | return self; | ||
1129 | } | ||
1130 | |||
1131 | -(id) copyWithZone: (NSZone*) zone | ||
1132 | { | ||
1133 | return[(CCTintBy*)[[self class] allocWithZone: zone] initWithDuration: [self duration] red:deltaR_ green:deltaG_ blue:deltaB_]; | ||
1134 | } | ||
1135 | |||
1136 | -(void) startWithTarget:(id)aTarget | ||
1137 | { | ||
1138 | [super startWithTarget:aTarget]; | ||
1139 | |||
1140 | id<CCRGBAProtocol> tn = (id<CCRGBAProtocol>) target_; | ||
1141 | ccColor3B color = [tn color]; | ||
1142 | fromR_ = color.r; | ||
1143 | fromG_ = color.g; | ||
1144 | fromB_ = color.b; | ||
1145 | } | ||
1146 | |||
1147 | -(void) update: (ccTime) t | ||
1148 | { | ||
1149 | id<CCRGBAProtocol> tn = (id<CCRGBAProtocol>) target_; | ||
1150 | [tn setColor:ccc3( fromR_ + deltaR_ * t, fromG_ + deltaG_ * t, fromB_ + deltaB_ * t)]; | ||
1151 | } | ||
1152 | |||
1153 | - (CCActionInterval*) reverse | ||
1154 | { | ||
1155 | return [CCTintBy actionWithDuration:duration_ red:-deltaR_ green:-deltaG_ blue:-deltaB_]; | ||
1156 | } | ||
1157 | @end | ||
1158 | |||
1159 | // | ||
1160 | // DelayTime | ||
1161 | // | ||
1162 | #pragma mark - | ||
1163 | #pragma mark DelayTime | ||
1164 | @implementation CCDelayTime | ||
1165 | -(void) update: (ccTime) t | ||
1166 | { | ||
1167 | return; | ||
1168 | } | ||
1169 | |||
1170 | -(id)reverse | ||
1171 | { | ||
1172 | return [[self class] actionWithDuration:duration_]; | ||
1173 | } | ||
1174 | @end | ||
1175 | |||
1176 | // | ||
1177 | // ReverseTime | ||
1178 | // | ||
1179 | #pragma mark - | ||
1180 | #pragma mark ReverseTime | ||
1181 | @implementation CCReverseTime | ||
1182 | +(id) actionWithAction: (CCFiniteTimeAction*) action | ||
1183 | { | ||
1184 | // casting to prevent warnings | ||
1185 | CCReverseTime *a = [super alloc]; | ||
1186 | return [[a initWithAction:action] autorelease]; | ||
1187 | } | ||
1188 | |||
1189 | -(id) initWithAction: (CCFiniteTimeAction*) action | ||
1190 | { | ||
1191 | NSAssert(action != nil, @"CCReverseTime: action should not be nil"); | ||
1192 | NSAssert(action != other_, @"CCReverseTime: re-init doesn't support using the same arguments"); | ||
1193 | |||
1194 | if( (self=[super initWithDuration: [action duration]]) ) { | ||
1195 | // Don't leak if action is reused | ||
1196 | [other_ release]; | ||
1197 | other_ = [action retain]; | ||
1198 | } | ||
1199 | |||
1200 | return self; | ||
1201 | } | ||
1202 | |||
1203 | -(id) copyWithZone: (NSZone*) zone | ||
1204 | { | ||
1205 | return [[[self class] allocWithZone: zone] initWithAction:[[other_ copy] autorelease] ]; | ||
1206 | } | ||
1207 | |||
1208 | -(void) dealloc | ||
1209 | { | ||
1210 | [other_ release]; | ||
1211 | [super dealloc]; | ||
1212 | } | ||
1213 | |||
1214 | -(void) startWithTarget:(id)aTarget | ||
1215 | { | ||
1216 | [super startWithTarget:aTarget]; | ||
1217 | [other_ startWithTarget:target_]; | ||
1218 | } | ||
1219 | |||
1220 | -(void) stop | ||
1221 | { | ||
1222 | [other_ stop]; | ||
1223 | [super stop]; | ||
1224 | } | ||
1225 | |||
1226 | -(void) update:(ccTime)t | ||
1227 | { | ||
1228 | [other_ update:1-t]; | ||
1229 | } | ||
1230 | |||
1231 | -(CCActionInterval*) reverse | ||
1232 | { | ||
1233 | return [[other_ copy] autorelease]; | ||
1234 | } | ||
1235 | @end | ||
1236 | |||
1237 | // | ||
1238 | // Animate | ||
1239 | // | ||
1240 | |||
1241 | #pragma mark - | ||
1242 | #pragma mark Animate | ||
1243 | @implementation CCAnimate | ||
1244 | |||
1245 | @synthesize animation = animation_; | ||
1246 | |||
1247 | +(id) actionWithAnimation: (CCAnimation*)anim | ||
1248 | { | ||
1249 | return [[[self alloc] initWithAnimation:anim restoreOriginalFrame:YES] autorelease]; | ||
1250 | } | ||
1251 | |||
1252 | +(id) actionWithAnimation: (CCAnimation*)anim restoreOriginalFrame:(BOOL)b | ||
1253 | { | ||
1254 | return [[[self alloc] initWithAnimation:anim restoreOriginalFrame:b] autorelease]; | ||
1255 | } | ||
1256 | |||
1257 | +(id) actionWithDuration:(ccTime)duration animation: (CCAnimation*)anim restoreOriginalFrame:(BOOL)b | ||
1258 | { | ||
1259 | return [[[self alloc] initWithDuration:duration animation:anim restoreOriginalFrame:b] autorelease]; | ||
1260 | } | ||
1261 | |||
1262 | -(id) initWithAnimation: (CCAnimation*)anim | ||
1263 | { | ||
1264 | NSAssert( anim!=nil, @"Animate: argument Animation must be non-nil"); | ||
1265 | return [self initWithAnimation:anim restoreOriginalFrame:YES]; | ||
1266 | } | ||
1267 | |||
1268 | -(id) initWithAnimation: (CCAnimation*)anim restoreOriginalFrame:(BOOL) b | ||
1269 | { | ||
1270 | NSAssert( anim!=nil, @"Animate: argument Animation must be non-nil"); | ||
1271 | |||
1272 | if( (self=[super initWithDuration: [[anim frames] count] * [anim delay]]) ) { | ||
1273 | |||
1274 | restoreOriginalFrame_ = b; | ||
1275 | self.animation = anim; | ||
1276 | origFrame_ = nil; | ||
1277 | } | ||
1278 | return self; | ||
1279 | } | ||
1280 | |||
1281 | -(id) initWithDuration:(ccTime)aDuration animation: (CCAnimation*)anim restoreOriginalFrame:(BOOL) b | ||
1282 | { | ||
1283 | NSAssert( anim!=nil, @"Animate: argument Animation must be non-nil"); | ||
1284 | |||
1285 | if( (self=[super initWithDuration:aDuration] ) ) { | ||
1286 | |||
1287 | restoreOriginalFrame_ = b; | ||
1288 | self.animation = anim; | ||
1289 | origFrame_ = nil; | ||
1290 | } | ||
1291 | return self; | ||
1292 | } | ||
1293 | |||
1294 | |||
1295 | -(id) copyWithZone: (NSZone*) zone | ||
1296 | { | ||
1297 | return [[[self class] allocWithZone: zone] initWithDuration:duration_ animation:animation_ restoreOriginalFrame:restoreOriginalFrame_]; | ||
1298 | } | ||
1299 | |||
1300 | -(void) dealloc | ||
1301 | { | ||
1302 | [animation_ release]; | ||
1303 | [origFrame_ release]; | ||
1304 | [super dealloc]; | ||
1305 | } | ||
1306 | |||
1307 | -(void) startWithTarget:(id)aTarget | ||
1308 | { | ||
1309 | [super startWithTarget:aTarget]; | ||
1310 | CCSprite *sprite = target_; | ||
1311 | |||
1312 | [origFrame_ release]; | ||
1313 | |||
1314 | if( restoreOriginalFrame_ ) | ||
1315 | origFrame_ = [[sprite displayedFrame] retain]; | ||
1316 | } | ||
1317 | |||
1318 | -(void) stop | ||
1319 | { | ||
1320 | if( restoreOriginalFrame_ ) { | ||
1321 | CCSprite *sprite = target_; | ||
1322 | [sprite setDisplayFrame:origFrame_]; | ||
1323 | } | ||
1324 | |||
1325 | [super stop]; | ||
1326 | } | ||
1327 | |||
1328 | -(void) update: (ccTime) t | ||
1329 | { | ||
1330 | NSArray *frames = [animation_ frames]; | ||
1331 | NSUInteger numberOfFrames = [frames count]; | ||
1332 | |||
1333 | NSUInteger idx = t * numberOfFrames; | ||
1334 | |||
1335 | if( idx >= numberOfFrames ) | ||
1336 | idx = numberOfFrames -1; | ||
1337 | |||
1338 | CCSprite *sprite = target_; | ||
1339 | if (! [sprite isFrameDisplayed: [frames objectAtIndex: idx]] ) | ||
1340 | [sprite setDisplayFrame: [frames objectAtIndex:idx]]; | ||
1341 | } | ||
1342 | |||
1343 | - (CCActionInterval *) reverse | ||
1344 | { | ||
1345 | NSArray *oldArray = [animation_ frames]; | ||
1346 | NSMutableArray *newArray = [NSMutableArray arrayWithCapacity:[oldArray count]]; | ||
1347 | NSEnumerator *enumerator = [oldArray reverseObjectEnumerator]; | ||
1348 | for (id element in enumerator) | ||
1349 | [newArray addObject:[[element copy] autorelease]]; | ||
1350 | |||
1351 | CCAnimation *newAnim = [CCAnimation animationWithFrames:newArray delay:animation_.delay]; | ||
1352 | return [[self class] actionWithDuration:duration_ animation:newAnim restoreOriginalFrame:restoreOriginalFrame_]; | ||
1353 | } | ||
1354 | |||
1355 | @end | ||