/libs/cocos2d/CCIntervalAction.m

http://github.com/kstenerud/ObjectAL-for-iPhone · Objective C · 1216 lines · 906 code · 193 blank · 117 comment · 52 complexity · 052a65f3e4833183d1634fc648525c8f MD5 · raw file

  1. /*
  2. * cocos2d for iPhone: http://www.cocos2d-iphone.org
  3. *
  4. * Copyright (c) 2008-2010 Ricardo Quesada
  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. #import "CCIntervalAction.h"
  26. #import "CCSprite.h"
  27. #import "CCSpriteFrame.h"
  28. #import "CCNode.h"
  29. #import "Support/CGPointExtension.h"
  30. //
  31. // IntervalAction
  32. //
  33. #pragma mark -
  34. #pragma mark IntervalAction
  35. @implementation CCIntervalAction
  36. @synthesize elapsed;
  37. -(id) init
  38. {
  39. NSException* myException = [NSException
  40. exceptionWithName:@"IntervalActionInit"
  41. reason:@"Init not supported. Use InitWithDuration"
  42. userInfo:nil];
  43. @throw myException;
  44. }
  45. +(id) actionWithDuration: (ccTime) d
  46. {
  47. return [[[self alloc] initWithDuration:d ] autorelease];
  48. }
  49. -(id) initWithDuration: (ccTime) d
  50. {
  51. if( (self=[super init]) ) {
  52. duration = d;
  53. // prevent division by 0
  54. // This comparison could be in step:, but it might decrease the performance
  55. // by 3% in heavy based action games.
  56. if( duration == 0 )
  57. duration = FLT_EPSILON;
  58. elapsed = 0;
  59. firstTick = YES;
  60. }
  61. return self;
  62. }
  63. -(id) copyWithZone: (NSZone*) zone
  64. {
  65. CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] ];
  66. return copy;
  67. }
  68. - (BOOL) isDone
  69. {
  70. return (elapsed >= duration);
  71. }
  72. -(void) step: (ccTime) dt
  73. {
  74. if( firstTick ) {
  75. firstTick = NO;
  76. elapsed = 0;
  77. } else
  78. elapsed += dt;
  79. [self update: MIN(1, elapsed/duration)];
  80. }
  81. -(void) startWithTarget:(id)aTarget
  82. {
  83. [super startWithTarget:aTarget];
  84. elapsed = 0.0f;
  85. firstTick = YES;
  86. }
  87. - (CCIntervalAction*) reverse
  88. {
  89. NSException* myException = [NSException
  90. exceptionWithName:@"ReverseActionNotImplemented"
  91. reason:@"Reverse Action not implemented"
  92. userInfo:nil];
  93. @throw myException;
  94. }
  95. @end
  96. //
  97. // Sequence
  98. //
  99. #pragma mark -
  100. #pragma mark Sequence
  101. @implementation CCSequence
  102. +(id) actionOne: (CCFiniteTimeAction*) one two: (CCFiniteTimeAction*) two
  103. {
  104. return [[[self alloc] initOne:one two:two ] autorelease];
  105. }
  106. +(id) actions: (CCFiniteTimeAction*) action1, ...
  107. {
  108. va_list params;
  109. va_start(params,action1);
  110. CCFiniteTimeAction *now;
  111. CCFiniteTimeAction *prev = action1;
  112. while( action1 ) {
  113. now = va_arg(params,CCFiniteTimeAction*);
  114. if ( now )
  115. prev = [self actionOne: prev two: now];
  116. else
  117. break;
  118. }
  119. va_end(params);
  120. return prev;
  121. }
  122. -(id) initOne: (CCFiniteTimeAction*) one_ two: (CCFiniteTimeAction*) two_
  123. {
  124. NSAssert( one_!=nil, @"Sequence: argument one must be non-nil");
  125. NSAssert( two_!=nil, @"Sequence: argument two must be non-nil");
  126. CCFiniteTimeAction *one = one_;
  127. CCFiniteTimeAction *two = two_;
  128. ccTime d = [one duration] + [two duration];
  129. [super initWithDuration: d];
  130. actions[0] = [one retain];
  131. actions[1] = [two retain];
  132. return self;
  133. }
  134. -(id) copyWithZone: (NSZone*) zone
  135. {
  136. CCAction *copy = [[[self class] allocWithZone:zone] initOne:[[actions[0] copy] autorelease] two:[[actions[1] copy] autorelease] ];
  137. return copy;
  138. }
  139. -(void) dealloc
  140. {
  141. [actions[0] release];
  142. [actions[1] release];
  143. [super dealloc];
  144. }
  145. -(void) startWithTarget:(id)aTarget
  146. {
  147. [super startWithTarget:aTarget];
  148. split = [actions[0] duration] / duration;
  149. last = -1;
  150. }
  151. -(void) stop
  152. {
  153. [actions[0] stop];
  154. [actions[1] stop];
  155. [super stop];
  156. }
  157. -(void) update: (ccTime) t
  158. {
  159. int found = 0;
  160. ccTime new_t = 0.0f;
  161. if( t >= split ) {
  162. found = 1;
  163. if ( split == 1 )
  164. new_t = 1;
  165. else
  166. new_t = (t-split) / (1 - split );
  167. } else {
  168. found = 0;
  169. if( split != 0 )
  170. new_t = t / split;
  171. else
  172. new_t = 1;
  173. }
  174. if (last == -1 && found==1) {
  175. [actions[0] startWithTarget:target];
  176. [actions[0] update:1.0f];
  177. [actions[0] stop];
  178. }
  179. if (last != found ) {
  180. if( last != -1 ) {
  181. [actions[last] update: 1.0f];
  182. [actions[last] stop];
  183. }
  184. [actions[found] startWithTarget:target];
  185. }
  186. [actions[found] update: new_t];
  187. last = found;
  188. }
  189. - (CCIntervalAction *) reverse
  190. {
  191. return [[self class] actionOne: [actions[1] reverse] two: [actions[0] reverse ] ];
  192. }
  193. @end
  194. //
  195. // Repeat
  196. //
  197. #pragma mark -
  198. #pragma mark CCRepeat
  199. @implementation CCRepeat
  200. +(id) actionWithAction:(CCFiniteTimeAction*)action times:(unsigned int)times
  201. {
  202. return [[[self alloc] initWithAction:action times:times] autorelease];
  203. }
  204. -(id) initWithAction:(CCFiniteTimeAction*)action times:(unsigned int)times
  205. {
  206. ccTime d = [action duration] * times;
  207. if( (self=[super initWithDuration: d ]) ) {
  208. times_ = times;
  209. other_ = [action retain];
  210. total_ = 0;
  211. }
  212. return self;
  213. }
  214. -(id) copyWithZone: (NSZone*) zone
  215. {
  216. CCAction *copy = [[[self class] allocWithZone:zone] initWithAction:[[other_ copy] autorelease] times:times_];
  217. return copy;
  218. }
  219. -(void) dealloc
  220. {
  221. [other_ release];
  222. [super dealloc];
  223. }
  224. -(void) startWithTarget:(id)aTarget
  225. {
  226. total_ = 0;
  227. [super startWithTarget:aTarget];
  228. [other_ startWithTarget:aTarget];
  229. }
  230. -(void) stop
  231. {
  232. [other_ stop];
  233. [super stop];
  234. }
  235. // issue #80. Instead of hooking step:, hook update: since it can be called by any
  236. // container action like Repeat, Sequence, AccelDeccel, etc..
  237. -(void) update:(ccTime) dt
  238. {
  239. ccTime t = dt * times_;
  240. if( t > total_+1 ) {
  241. [other_ update:1.0f];
  242. total_++;
  243. [other_ stop];
  244. [other_ startWithTarget:target];
  245. // repeat is over ?
  246. if( total_== times_ )
  247. // so, set it in the original position
  248. [other_ update:0];
  249. else {
  250. // no ? start next repeat with the right update
  251. // to prevent jerk (issue #390)
  252. [other_ update: t-total_];
  253. }
  254. } else {
  255. float r = fmodf(t, 1.0f);
  256. // fix last repeat position
  257. // else it could be 0.
  258. if( dt== 1.0f) {
  259. r=1.0f;
  260. total_++; // this is the added line
  261. }
  262. [other_ update: MIN(r,1)];
  263. }
  264. }
  265. -(BOOL) isDone
  266. {
  267. return ( total_ == times_ );
  268. }
  269. - (CCIntervalAction *) reverse
  270. {
  271. return [[self class] actionWithAction:[other_ reverse] times:times_];
  272. }
  273. @end
  274. //
  275. // Spawn
  276. //
  277. #pragma mark -
  278. #pragma mark Spawn
  279. @implementation CCSpawn
  280. +(id) actions: (CCFiniteTimeAction*) action1, ...
  281. {
  282. va_list params;
  283. va_start(params,action1);
  284. CCFiniteTimeAction *now;
  285. CCFiniteTimeAction *prev = action1;
  286. while( action1 ) {
  287. now = va_arg(params,CCFiniteTimeAction*);
  288. if ( now )
  289. prev = [self actionOne: prev two: now];
  290. else
  291. break;
  292. }
  293. va_end(params);
  294. return prev;
  295. }
  296. +(id) actionOne: (CCFiniteTimeAction*) one two: (CCFiniteTimeAction*) two
  297. {
  298. return [[[self alloc] initOne:one two:two ] autorelease];
  299. }
  300. -(id) initOne: (CCFiniteTimeAction*) one_ two: (CCFiniteTimeAction*) two_
  301. {
  302. NSAssert( one_!=nil, @"Spawn: argument one must be non-nil");
  303. NSAssert( two_!=nil, @"Spawn: argument two must be non-nil");
  304. ccTime d1 = [one_ duration];
  305. ccTime d2 = [two_ duration];
  306. [super initWithDuration: fmaxf(d1,d2)];
  307. one = one_;
  308. two = two_;
  309. if( d1 > d2 )
  310. two = [CCSequence actionOne: two_ two:[CCDelayTime actionWithDuration: (d1-d2)] ];
  311. else if( d1 < d2)
  312. one = [CCSequence actionOne: one_ two: [CCDelayTime actionWithDuration: (d2-d1)] ];
  313. [one retain];
  314. [two retain];
  315. return self;
  316. }
  317. -(id) copyWithZone: (NSZone*) zone
  318. {
  319. CCAction *copy = [[[self class] allocWithZone: zone] initOne: [[one copy] autorelease] two: [[two copy] autorelease] ];
  320. return copy;
  321. }
  322. -(void) dealloc
  323. {
  324. [one release];
  325. [two release];
  326. [super dealloc];
  327. }
  328. -(void) startWithTarget:(id)aTarget
  329. {
  330. [super startWithTarget:aTarget];
  331. [one startWithTarget:target];
  332. [two startWithTarget:target];
  333. }
  334. -(void) stop
  335. {
  336. [one stop];
  337. [two stop];
  338. [super stop];
  339. }
  340. -(void) update: (ccTime) t
  341. {
  342. [one update:t];
  343. [two update:t];
  344. }
  345. - (CCIntervalAction *) reverse
  346. {
  347. return [[self class] actionOne: [one reverse] two: [two reverse ] ];
  348. }
  349. @end
  350. //
  351. // RotateTo
  352. //
  353. #pragma mark -
  354. #pragma mark RotateTo
  355. @implementation CCRotateTo
  356. +(id) actionWithDuration: (ccTime) t angle:(float) a
  357. {
  358. return [[[self alloc] initWithDuration:t angle:a ] autorelease];
  359. }
  360. -(id) initWithDuration: (ccTime) t angle:(float) a
  361. {
  362. if( (self=[super initWithDuration: t]) ) {
  363. dstAngle = a;
  364. }
  365. return self;
  366. }
  367. -(id) copyWithZone: (NSZone*) zone
  368. {
  369. CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration:[self duration] angle: dstAngle];
  370. return copy;
  371. }
  372. -(void) startWithTarget:(CCNode *)aTarget
  373. {
  374. [super startWithTarget:aTarget];
  375. startAngle = [target rotation];
  376. if (startAngle > 0)
  377. startAngle = fmodf(startAngle, 360.0f);
  378. else
  379. startAngle = fmodf(startAngle, -360.0f);
  380. diffAngle = dstAngle - startAngle;
  381. if (diffAngle > 180)
  382. diffAngle -= 360;
  383. if (diffAngle < -180)
  384. diffAngle += 360;
  385. }
  386. -(void) update: (ccTime) t
  387. {
  388. [target setRotation: startAngle + diffAngle * t];
  389. }
  390. @end
  391. //
  392. // RotateBy
  393. //
  394. #pragma mark -
  395. #pragma mark RotateBy
  396. @implementation CCRotateBy
  397. +(id) actionWithDuration: (ccTime) t angle:(float) a
  398. {
  399. return [[[self alloc] initWithDuration:t angle:a ] autorelease];
  400. }
  401. -(id) initWithDuration: (ccTime) t angle:(float) a
  402. {
  403. if( (self=[super initWithDuration: t]) ) {
  404. angle = a;
  405. }
  406. return self;
  407. }
  408. -(id) copyWithZone: (NSZone*) zone
  409. {
  410. CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] angle: angle];
  411. return copy;
  412. }
  413. -(void) startWithTarget:(id)aTarget
  414. {
  415. [super startWithTarget:aTarget];
  416. startAngle = [target rotation];
  417. }
  418. -(void) update: (ccTime) t
  419. {
  420. // XXX: shall I add % 360
  421. [target setRotation: (startAngle + angle * t )];
  422. }
  423. -(CCIntervalAction*) reverse
  424. {
  425. return [[self class] actionWithDuration: duration angle: -angle];
  426. }
  427. @end
  428. //
  429. // MoveTo
  430. //
  431. #pragma mark -
  432. #pragma mark MoveTo
  433. @implementation CCMoveTo
  434. +(id) actionWithDuration: (ccTime) t position: (CGPoint) p
  435. {
  436. return [[[self alloc] initWithDuration:t position:p ] autorelease];
  437. }
  438. -(id) initWithDuration: (ccTime) t position: (CGPoint) p
  439. {
  440. if( (self=[super initWithDuration: t]) ) {
  441. endPosition = p;
  442. }
  443. return self;
  444. }
  445. -(id) copyWithZone: (NSZone*) zone
  446. {
  447. CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] position: endPosition];
  448. return copy;
  449. }
  450. -(void) startWithTarget:(CCNode *)aTarget
  451. {
  452. [super startWithTarget:aTarget];
  453. startPosition = [(CCNode*)target position];
  454. delta = ccpSub( endPosition, startPosition );
  455. }
  456. -(void) update: (ccTime) t
  457. {
  458. [target setPosition: ccp( (startPosition.x + delta.x * t ), (startPosition.y + delta.y * t ) )];
  459. }
  460. @end
  461. //
  462. // MoveBy
  463. //
  464. #pragma mark -
  465. #pragma mark MoveBy
  466. @implementation CCMoveBy
  467. +(id) actionWithDuration: (ccTime) t position: (CGPoint) p
  468. {
  469. return [[[self alloc] initWithDuration:t position:p ] autorelease];
  470. }
  471. -(id) initWithDuration: (ccTime) t position: (CGPoint) p
  472. {
  473. if( (self=[super initWithDuration: t]) ) {
  474. delta = p;
  475. }
  476. return self;
  477. }
  478. -(id) copyWithZone: (NSZone*) zone
  479. {
  480. CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] position: delta];
  481. return copy;
  482. }
  483. -(void) startWithTarget:(CCNode *)aTarget
  484. {
  485. CGPoint dTmp = delta;
  486. [super startWithTarget:aTarget];
  487. delta = dTmp;
  488. }
  489. -(CCIntervalAction*) reverse
  490. {
  491. return [[self class] actionWithDuration: duration position: ccp( -delta.x, -delta.y)];
  492. }
  493. @end
  494. //
  495. // JumpBy
  496. //
  497. #pragma mark -
  498. #pragma mark JumpBy
  499. @implementation CCJumpBy
  500. +(id) actionWithDuration: (ccTime) t position: (CGPoint) pos height: (ccTime) h jumps:(int)j
  501. {
  502. return [[[self alloc] initWithDuration: t position: pos height: h jumps:j] autorelease];
  503. }
  504. -(id) initWithDuration: (ccTime) t position: (CGPoint) pos height: (ccTime) h jumps:(int)j
  505. {
  506. if( (self=[super initWithDuration:t]) ) {
  507. delta = pos;
  508. height = h;
  509. jumps = j;
  510. }
  511. return self;
  512. }
  513. -(id) copyWithZone: (NSZone*) zone
  514. {
  515. CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] position: delta height:height jumps:jumps];
  516. return copy;
  517. }
  518. -(void) startWithTarget:(id)aTarget
  519. {
  520. [super startWithTarget:aTarget];
  521. startPosition = [(CCNode*)target position];
  522. }
  523. -(void) update: (ccTime) t
  524. {
  525. // Sin jump. Less realistic
  526. // ccTime y = height * fabsf( sinf(t * (CGFloat)M_PI * jumps ) );
  527. // y += delta.y * t;
  528. // ccTime x = delta.x * t;
  529. // [target setPosition: ccp( startPosition.x + x, startPosition.y + y )];
  530. // parabolic jump (since v0.8.2)
  531. ccTime frac = fmodf( t * jumps, 1.0f );
  532. ccTime y = height * 4 * frac * (1 - frac);
  533. y += delta.y * t;
  534. ccTime x = delta.x * t;
  535. [target setPosition: ccp( startPosition.x + x, startPosition.y + y )];
  536. }
  537. -(CCIntervalAction*) reverse
  538. {
  539. return [[self class] actionWithDuration: duration position: ccp(-delta.x,-delta.y) height: height jumps:jumps];
  540. }
  541. @end
  542. //
  543. // JumpTo
  544. //
  545. #pragma mark -
  546. #pragma mark JumpTo
  547. @implementation CCJumpTo
  548. -(void) startWithTarget:(CCNode *)aTarget
  549. {
  550. [super startWithTarget:aTarget];
  551. delta = ccp( delta.x - startPosition.x, delta.y - startPosition.y );
  552. }
  553. @end
  554. #pragma mark -
  555. #pragma mark BezierBy
  556. // Bezier cubic formula:
  557. // ((1 - t) + t)3 = 1
  558. // Expands to…
  559. // (1 - t)3 + 3t(1-t)2 + 3t2(1 - t) + t3 = 1
  560. static inline float bezierat( float a, float b, float c, float d, ccTime t )
  561. {
  562. return (powf(1-t,3) * a +
  563. 3*t*(powf(1-t,2))*b +
  564. 3*powf(t,2)*(1-t)*c +
  565. powf(t,3)*d );
  566. }
  567. //
  568. // BezierBy
  569. //
  570. @implementation CCBezierBy
  571. +(id) actionWithDuration: (ccTime) t bezier:(ccBezierConfig) c
  572. {
  573. return [[[self alloc] initWithDuration:t bezier:c ] autorelease];
  574. }
  575. -(id) initWithDuration: (ccTime) t bezier:(ccBezierConfig) c
  576. {
  577. if( (self=[super initWithDuration: t]) ) {
  578. config = c;
  579. }
  580. return self;
  581. }
  582. -(id) copyWithZone: (NSZone*) zone
  583. {
  584. CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] bezier: config];
  585. return copy;
  586. }
  587. -(void) startWithTarget:(id)aTarget
  588. {
  589. [super startWithTarget:aTarget];
  590. startPosition = [(CCNode*)target position];
  591. }
  592. -(void) update: (ccTime) t
  593. {
  594. float xa = 0;
  595. float xb = config.controlPoint_1.x;
  596. float xc = config.controlPoint_2.x;
  597. float xd = config.endPosition.x;
  598. float ya = 0;
  599. float yb = config.controlPoint_1.y;
  600. float yc = config.controlPoint_2.y;
  601. float yd = config.endPosition.y;
  602. float x = bezierat(xa, xb, xc, xd, t);
  603. float y = bezierat(ya, yb, yc, yd, t);
  604. [target setPosition: ccpAdd( startPosition, ccp(x,y))];
  605. }
  606. - (CCIntervalAction*) reverse
  607. {
  608. ccBezierConfig r;
  609. r.endPosition = ccpNeg(config.endPosition);
  610. r.controlPoint_1 = ccpAdd(config.controlPoint_2, ccpNeg(config.endPosition));
  611. r.controlPoint_2 = ccpAdd(config.controlPoint_1, ccpNeg(config.endPosition));
  612. CCBezierBy *action = [[self class] actionWithDuration:[self duration] bezier:r];
  613. return action;
  614. }
  615. @end
  616. //
  617. // BezierTo
  618. //
  619. #pragma mark -
  620. #pragma mark BezierTo
  621. @implementation CCBezierTo
  622. -(void) startWithTarget:(id)aTarget
  623. {
  624. [super startWithTarget:aTarget];
  625. config.controlPoint_1 = ccpSub(config.controlPoint_1, startPosition);
  626. config.controlPoint_2 = ccpSub(config.controlPoint_2, startPosition);
  627. config.endPosition = ccpSub(config.endPosition, startPosition);
  628. }
  629. @end
  630. //
  631. // ScaleTo
  632. //
  633. #pragma mark -
  634. #pragma mark ScaleTo
  635. @implementation CCScaleTo
  636. +(id) actionWithDuration: (ccTime) t scale:(float) s
  637. {
  638. return [[[self alloc] initWithDuration: t scale:s] autorelease];
  639. }
  640. -(id) initWithDuration: (ccTime) t scale:(float) s
  641. {
  642. if( (self=[super initWithDuration: t]) ) {
  643. endScaleX = s;
  644. endScaleY = s;
  645. }
  646. return self;
  647. }
  648. +(id) actionWithDuration: (ccTime) t scaleX:(float)sx scaleY:(float)sy
  649. {
  650. return [[[self alloc] initWithDuration: t scaleX:sx scaleY:sy] autorelease];
  651. }
  652. -(id) initWithDuration: (ccTime) t scaleX:(float)sx scaleY:(float)sy
  653. {
  654. if( (self=[super initWithDuration: t]) ) {
  655. endScaleX = sx;
  656. endScaleY = sy;
  657. }
  658. return self;
  659. }
  660. -(id) copyWithZone: (NSZone*) zone
  661. {
  662. CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] scaleX:endScaleX scaleY:endScaleY];
  663. return copy;
  664. }
  665. -(void) startWithTarget:(CCNode *)aTarget
  666. {
  667. [super startWithTarget:aTarget];
  668. startScaleX = [target scaleX];
  669. startScaleY = [target scaleY];
  670. deltaX = endScaleX - startScaleX;
  671. deltaY = endScaleY - startScaleY;
  672. }
  673. -(void) update: (ccTime) t
  674. {
  675. [target setScaleX: (startScaleX + deltaX * t ) ];
  676. [target setScaleY: (startScaleY + deltaY * t ) ];
  677. }
  678. @end
  679. //
  680. // ScaleBy
  681. //
  682. #pragma mark -
  683. #pragma mark ScaleBy
  684. @implementation CCScaleBy
  685. -(void) startWithTarget:(CCNode *)aTarget
  686. {
  687. [super startWithTarget:aTarget];
  688. deltaX = startScaleX * endScaleX - startScaleX;
  689. deltaY = startScaleY * endScaleY - startScaleY;
  690. }
  691. -(CCIntervalAction*) reverse
  692. {
  693. return [[self class] actionWithDuration: duration scaleX: 1/endScaleX scaleY:1/endScaleY];
  694. }
  695. @end
  696. //
  697. // Blink
  698. //
  699. #pragma mark -
  700. #pragma mark Blink
  701. @implementation CCBlink
  702. +(id) actionWithDuration: (ccTime) t blinks: (unsigned int) b
  703. {
  704. return [[[ self alloc] initWithDuration: t blinks: b] autorelease];
  705. }
  706. -(id) initWithDuration: (ccTime) t blinks: (unsigned int) b
  707. {
  708. if( (self=[super initWithDuration: t] ) ) {
  709. times = b;
  710. }
  711. return self;
  712. }
  713. -(id) copyWithZone: (NSZone*) zone
  714. {
  715. CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] blinks: times];
  716. return copy;
  717. }
  718. -(void) update: (ccTime) t
  719. {
  720. ccTime slice = 1.0f / times;
  721. ccTime m = fmodf(t, slice);
  722. [target setVisible: (m > slice/2) ? YES : NO];
  723. }
  724. -(CCIntervalAction*) reverse
  725. {
  726. // return 'self'
  727. return [[self class] actionWithDuration: duration blinks: times];
  728. }
  729. @end
  730. //
  731. // FadeIn
  732. //
  733. #pragma mark -
  734. #pragma mark FadeIn
  735. @implementation CCFadeIn
  736. -(void) update: (ccTime) t
  737. {
  738. [(id<CCRGBAProtocol>) target setOpacity: 255 *t];
  739. }
  740. -(CCIntervalAction*) reverse
  741. {
  742. return [CCFadeOut actionWithDuration: duration];
  743. }
  744. @end
  745. //
  746. // FadeOut
  747. //
  748. #pragma mark -
  749. #pragma mark FadeOut
  750. @implementation CCFadeOut
  751. -(void) update: (ccTime) t
  752. {
  753. [(id<CCRGBAProtocol>) target setOpacity: 255 *(1-t)];
  754. }
  755. -(CCIntervalAction*) reverse
  756. {
  757. return [CCFadeIn actionWithDuration: duration];
  758. }
  759. @end
  760. //
  761. // FadeTo
  762. //
  763. #pragma mark -
  764. #pragma mark FadeTo
  765. @implementation CCFadeTo
  766. +(id) actionWithDuration: (ccTime) t opacity: (GLubyte) o
  767. {
  768. return [[[ self alloc] initWithDuration: t opacity: o] autorelease];
  769. }
  770. -(id) initWithDuration: (ccTime) t opacity: (GLubyte) o
  771. {
  772. if( (self=[super initWithDuration: t] ) )
  773. toOpacity = o;
  774. return self;
  775. }
  776. -(id) copyWithZone: (NSZone*) zone
  777. {
  778. CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] opacity: toOpacity];
  779. return copy;
  780. }
  781. -(void) startWithTarget:(CCNode *)aTarget
  782. {
  783. [super startWithTarget:aTarget];
  784. fromOpacity = [(id<CCRGBAProtocol>)target opacity];
  785. }
  786. -(void) update: (ccTime) t
  787. {
  788. [(id<CCRGBAProtocol>)target setOpacity: fromOpacity + ( toOpacity - fromOpacity ) * t];
  789. }
  790. @end
  791. //
  792. // TintTo
  793. //
  794. #pragma mark -
  795. #pragma mark TintTo
  796. @implementation CCTintTo
  797. +(id) actionWithDuration:(ccTime)t red:(GLubyte)r green:(GLubyte)g blue:(GLubyte)b
  798. {
  799. return [[(CCTintTo*)[ self alloc] initWithDuration:t red:r green:g blue:b] autorelease];
  800. }
  801. -(id) initWithDuration: (ccTime) t red:(GLubyte)r green:(GLubyte)g blue:(GLubyte)b
  802. {
  803. if( (self=[super initWithDuration: t] ) ) {
  804. to = ccc3(r,g,b);
  805. }
  806. return self;
  807. }
  808. -(id) copyWithZone: (NSZone*) zone
  809. {
  810. CCAction *copy = [(CCTintTo*)[[self class] allocWithZone: zone] initWithDuration: [self duration] red:to.r green:to.g blue:to.b];
  811. return copy;
  812. }
  813. -(void) startWithTarget:(id)aTarget
  814. {
  815. [super startWithTarget:aTarget];
  816. id<CCRGBAProtocol> tn = (id<CCRGBAProtocol>) target;
  817. from = [tn color];
  818. }
  819. -(void) update: (ccTime) t
  820. {
  821. id<CCRGBAProtocol> tn = (id<CCRGBAProtocol>) target;
  822. [tn setColor:ccc3(from.r + (to.r - from.r) * t, from.g + (to.g - from.g) * t, from.b + (to.b - from.b) * t)];
  823. }
  824. @end
  825. //
  826. // TintBy
  827. //
  828. #pragma mark -
  829. #pragma mark TintBy
  830. @implementation CCTintBy
  831. +(id) actionWithDuration:(ccTime)t red:(GLshort)r green:(GLshort)g blue:(GLshort)b
  832. {
  833. return [[(CCTintBy*)[ self alloc] initWithDuration:t red:r green:g blue:b] autorelease];
  834. }
  835. -(id) initWithDuration:(ccTime)t red:(GLshort)r green:(GLshort)g blue:(GLshort)b
  836. {
  837. if( (self=[super initWithDuration: t] ) ) {
  838. deltaR = r;
  839. deltaG = g;
  840. deltaB = b;
  841. }
  842. return self;
  843. }
  844. -(id) copyWithZone: (NSZone*) zone
  845. {
  846. return[(CCTintBy*)[[self class] allocWithZone: zone] initWithDuration: [self duration] red:deltaR green:deltaG blue:deltaB];
  847. }
  848. -(void) startWithTarget:(id)aTarget
  849. {
  850. [super startWithTarget:aTarget];
  851. id<CCRGBAProtocol> tn = (id<CCRGBAProtocol>) target;
  852. ccColor3B color = [tn color];
  853. fromR = color.r;
  854. fromG = color.g;
  855. fromB = color.b;
  856. }
  857. -(void) update: (ccTime) t
  858. {
  859. id<CCRGBAProtocol> tn = (id<CCRGBAProtocol>) target;
  860. [tn setColor:ccc3( fromR + deltaR * t, fromG + deltaG * t, fromB + deltaB * t)];
  861. }
  862. - (CCIntervalAction*) reverse
  863. {
  864. return [CCTintBy actionWithDuration:duration red:-deltaR green:-deltaG blue:-deltaB];
  865. }
  866. @end
  867. //
  868. // DelayTime
  869. //
  870. #pragma mark -
  871. #pragma mark DelayTime
  872. @implementation CCDelayTime
  873. -(void) update: (ccTime) t
  874. {
  875. return;
  876. }
  877. -(id)reverse
  878. {
  879. return [[self class] actionWithDuration:duration];
  880. }
  881. @end
  882. //
  883. // ReverseTime
  884. //
  885. #pragma mark -
  886. #pragma mark ReverseTime
  887. @implementation CCReverseTime
  888. +(id) actionWithAction: (CCFiniteTimeAction*) action
  889. {
  890. // casting to prevent warnings
  891. CCReverseTime *a = [super alloc];
  892. return [[a initWithAction:action] autorelease];
  893. }
  894. -(id) initWithAction: (CCFiniteTimeAction*) action
  895. {
  896. if( (self=[super initWithDuration: [action duration]]) ) {
  897. other = [action retain];
  898. }
  899. return self;
  900. }
  901. -(id) copyWithZone: (NSZone*) zone
  902. {
  903. return [[[self class] allocWithZone: zone] initWithAction:[[other copy] autorelease] ];
  904. }
  905. -(void) dealloc
  906. {
  907. [other release];
  908. [super dealloc];
  909. }
  910. -(void) startWithTarget:(id)aTarget
  911. {
  912. [super startWithTarget:aTarget];
  913. [other startWithTarget:target];
  914. }
  915. -(void) stop
  916. {
  917. [other stop];
  918. [super stop];
  919. }
  920. -(void) update:(ccTime)t
  921. {
  922. [other update:1-t];
  923. }
  924. -(CCIntervalAction*) reverse
  925. {
  926. return [[other copy] autorelease];
  927. }
  928. @end
  929. //
  930. // Animate
  931. //
  932. #pragma mark -
  933. #pragma mark Animate
  934. @implementation CCAnimate
  935. @synthesize animation = animation_;
  936. +(id) actionWithAnimation: (CCAnimation*)anim
  937. {
  938. return [[[self alloc] initWithAnimation:anim restoreOriginalFrame:YES] autorelease];
  939. }
  940. +(id) actionWithAnimation: (CCAnimation*)anim restoreOriginalFrame:(BOOL)b
  941. {
  942. return [[[self alloc] initWithAnimation:anim restoreOriginalFrame:b] autorelease];
  943. }
  944. +(id) actionWithDuration:(ccTime)duration animation: (CCAnimation*)anim restoreOriginalFrame:(BOOL)b
  945. {
  946. return [[[self alloc] initWithDuration:duration animation:anim restoreOriginalFrame:b] autorelease];
  947. }
  948. -(id) initWithAnimation: (CCAnimation*)anim
  949. {
  950. NSAssert( anim!=nil, @"Animate: argument Animation must be non-nil");
  951. return [self initWithAnimation:anim restoreOriginalFrame:YES];
  952. }
  953. -(id) initWithAnimation: (CCAnimation*)anim restoreOriginalFrame:(BOOL) b
  954. {
  955. NSAssert( anim!=nil, @"Animate: argument Animation must be non-nil");
  956. if( (self=[super initWithDuration: [[anim frames] count] * [anim delay]]) ) {
  957. restoreOriginalFrame = b;
  958. self.animation = anim;
  959. origFrame = nil;
  960. }
  961. return self;
  962. }
  963. -(id) initWithDuration:(ccTime)aDuration animation: (CCAnimation*)anim restoreOriginalFrame:(BOOL) b
  964. {
  965. NSAssert( anim!=nil, @"Animate: argument Animation must be non-nil");
  966. if( (self=[super initWithDuration:aDuration] ) ) {
  967. restoreOriginalFrame = b;
  968. self.animation = anim;
  969. origFrame = nil;
  970. }
  971. return self;
  972. }
  973. -(id) copyWithZone: (NSZone*) zone
  974. {
  975. return [[[self class] allocWithZone: zone] initWithDuration:duration animation:animation_ restoreOriginalFrame:restoreOriginalFrame];
  976. }
  977. -(void) dealloc
  978. {
  979. [animation_ release];
  980. [origFrame release];
  981. [super dealloc];
  982. }
  983. -(void) startWithTarget:(id)aTarget
  984. {
  985. [super startWithTarget:aTarget];
  986. CCSprite *sprite = target;
  987. [origFrame release];
  988. if( restoreOriginalFrame )
  989. origFrame = [[sprite displayedFrame] retain];
  990. }
  991. -(void) stop
  992. {
  993. if( restoreOriginalFrame ) {
  994. CCSprite *sprite = target;
  995. [sprite setDisplayFrame:origFrame];
  996. }
  997. [super stop];
  998. }
  999. -(void) update: (ccTime) t
  1000. {
  1001. NSArray *frames = [animation_ frames];
  1002. NSUInteger numberOfFrames = [frames count];
  1003. NSUInteger idx = t * numberOfFrames;
  1004. if( idx >= numberOfFrames ) {
  1005. idx = numberOfFrames -1;
  1006. }
  1007. CCSprite *sprite = target;
  1008. if (! [sprite isFrameDisplayed: [frames objectAtIndex: idx]] ) {
  1009. [sprite setDisplayFrame: [frames objectAtIndex:idx]];
  1010. }
  1011. }
  1012. - (CCIntervalAction *) reverse
  1013. {
  1014. NSArray *oldArray = [animation_ frames];
  1015. NSMutableArray *newArray = [NSMutableArray arrayWithCapacity:[oldArray count]];
  1016. NSEnumerator *enumerator = [oldArray reverseObjectEnumerator];
  1017. for (id element in enumerator) {
  1018. [newArray addObject:[[element copy] autorelease]];
  1019. }
  1020. CCAnimation *newAnim = [CCAnimation animationWithName:animation_.name delay:animation_.delay frames:newArray];
  1021. return [[self class] actionWithDuration:duration animation:newAnim restoreOriginalFrame:restoreOriginalFrame];
  1022. }
  1023. @end