summary refs log tree commit diff stats
path: root/libs/cocos2d/CCAction.m
diff options
context:
space:
mode:
Diffstat (limited to 'libs/cocos2d/CCAction.m')
-rwxr-xr-xlibs/cocos2d/CCAction.m360
1 files changed, 360 insertions, 0 deletions
diff --git a/libs/cocos2d/CCAction.m b/libs/cocos2d/CCAction.m new file mode 100755 index 0000000..27db20b --- /dev/null +++ b/libs/cocos2d/CCAction.m
@@ -0,0 +1,360 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2008-2010 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 <Availability.h>
30#import "CCDirector.h"
31#import "ccMacros.h"
32#import "CCAction.h"
33#import "CCActionInterval.h"
34#import "Support/CGPointExtension.h"
35
36//
37// Action Base Class
38//
39#pragma mark -
40#pragma mark Action
41@implementation CCAction
42
43@synthesize tag = tag_, target = target_, originalTarget = originalTarget_;
44
45+(id) action
46{
47 return [[[self alloc] init] autorelease];
48}
49
50-(id) init
51{
52 if( (self=[super init]) ) {
53 originalTarget_ = target_ = nil;
54 tag_ = kCCActionTagInvalid;
55 }
56 return self;
57}
58
59-(void) dealloc
60{
61 CCLOGINFO(@"cocos2d: deallocing %@", self);
62 [super dealloc];
63}
64
65-(NSString*) description
66{
67 return [NSString stringWithFormat:@"<%@ = %08X | Tag = %i>", [self class], self, tag_];
68}
69
70-(id) copyWithZone: (NSZone*) zone
71{
72 CCAction *copy = [[[self class] allocWithZone: zone] init];
73 copy.tag = tag_;
74 return copy;
75}
76
77-(void) startWithTarget:(id)aTarget
78{
79 originalTarget_ = target_ = aTarget;
80}
81
82-(void) stop
83{
84 target_ = nil;
85}
86
87-(BOOL) isDone
88{
89 return YES;
90}
91
92-(void) step: (ccTime) dt
93{
94 NSLog(@"[Action step]. override me");
95}
96
97-(void) update: (ccTime) time
98{
99 NSLog(@"[Action update]. override me");
100}
101@end
102
103//
104// FiniteTimeAction
105//
106#pragma mark -
107#pragma mark FiniteTimeAction
108@implementation CCFiniteTimeAction
109@synthesize duration = duration_;
110
111- (CCFiniteTimeAction*) reverse
112{
113 CCLOG(@"cocos2d: FiniteTimeAction#reverse: Implement me");
114 return nil;
115}
116@end
117
118
119//
120// RepeatForever
121//
122#pragma mark -
123#pragma mark RepeatForever
124@implementation CCRepeatForever
125@synthesize innerAction=innerAction_;
126+(id) actionWithAction: (CCActionInterval*) action
127{
128 return [[[self alloc] initWithAction: action] autorelease];
129}
130
131-(id) initWithAction: (CCActionInterval*) action
132{
133 if( (self=[super init]) )
134 self.innerAction = action;
135
136 return self;
137}
138
139-(id) copyWithZone: (NSZone*) zone
140{
141 CCAction *copy = [[[self class] allocWithZone: zone] initWithAction:[[innerAction_ copy] autorelease] ];
142 return copy;
143}
144
145-(void) dealloc
146{
147 [innerAction_ release];
148 [super dealloc];
149}
150
151-(void) startWithTarget:(id)aTarget
152{
153 [super startWithTarget:aTarget];
154 [innerAction_ startWithTarget:target_];
155}
156
157-(void) step:(ccTime) dt
158{
159 [innerAction_ step: dt];
160 if( [innerAction_ isDone] ) {
161 ccTime diff = dt + innerAction_.duration - innerAction_.elapsed;
162 [innerAction_ startWithTarget:target_];
163
164 // to prevent jerk. issue #390
165 [innerAction_ step: diff];
166 }
167}
168
169
170-(BOOL) isDone
171{
172 return NO;
173}
174
175- (CCActionInterval *) reverse
176{
177 return [CCRepeatForever actionWithAction:[innerAction_ reverse]];
178}
179@end
180
181//
182// Speed
183//
184#pragma mark -
185#pragma mark Speed
186@implementation CCSpeed
187@synthesize speed=speed_;
188@synthesize innerAction=innerAction_;
189
190+(id) actionWithAction: (CCActionInterval*) action speed:(float)r
191{
192 return [[[self alloc] initWithAction: action speed:r] autorelease];
193}
194
195-(id) initWithAction: (CCActionInterval*) action speed:(float)r
196{
197 if( (self=[super init]) ) {
198 self.innerAction = action;
199 speed_ = r;
200 }
201 return self;
202}
203
204-(id) copyWithZone: (NSZone*) zone
205{
206 CCAction *copy = [[[self class] allocWithZone: zone] initWithAction:[[innerAction_ copy] autorelease] speed:speed_];
207 return copy;
208}
209
210-(void) dealloc
211{
212 [innerAction_ release];
213 [super dealloc];
214}
215
216-(void) startWithTarget:(id)aTarget
217{
218 [super startWithTarget:aTarget];
219 [innerAction_ startWithTarget:target_];
220}
221
222-(void) stop
223{
224 [innerAction_ stop];
225 [super stop];
226}
227
228-(void) step:(ccTime) dt
229{
230 [innerAction_ step: dt * speed_];
231}
232
233-(BOOL) isDone
234{
235 return [innerAction_ isDone];
236}
237
238- (CCActionInterval *) reverse
239{
240 return [CCSpeed actionWithAction:[innerAction_ reverse] speed:speed_];
241}
242@end
243
244//
245// Follow
246//
247#pragma mark -
248#pragma mark Follow
249@implementation CCFollow
250
251@synthesize boundarySet;
252
253+(id) actionWithTarget:(CCNode *) fNode
254{
255 return [[[self alloc] initWithTarget:fNode] autorelease];
256}
257
258+(id) actionWithTarget:(CCNode *) fNode worldBoundary:(CGRect)rect
259{
260 return [[[self alloc] initWithTarget:fNode worldBoundary:rect] autorelease];
261}
262
263-(id) initWithTarget:(CCNode *)fNode
264{
265 if( (self=[super init]) ) {
266
267 followedNode_ = [fNode retain];
268 boundarySet = FALSE;
269 boundaryFullyCovered = FALSE;
270
271 CGSize s = [[CCDirector sharedDirector] winSize];
272 fullScreenSize = CGPointMake(s.width, s.height);
273 halfScreenSize = ccpMult(fullScreenSize, .5f);
274 }
275
276 return self;
277}
278
279-(id) initWithTarget:(CCNode *)fNode worldBoundary:(CGRect)rect
280{
281 if( (self=[super init]) ) {
282
283 followedNode_ = [fNode retain];
284 boundarySet = TRUE;
285 boundaryFullyCovered = FALSE;
286
287 CGSize winSize = [[CCDirector sharedDirector] winSize];
288 fullScreenSize = CGPointMake(winSize.width, winSize.height);
289 halfScreenSize = ccpMult(fullScreenSize, .5f);
290
291 leftBoundary = -((rect.origin.x+rect.size.width) - fullScreenSize.x);
292 rightBoundary = -rect.origin.x ;
293 topBoundary = -rect.origin.y;
294 bottomBoundary = -((rect.origin.y+rect.size.height) - fullScreenSize.y);
295
296 if(rightBoundary < leftBoundary)
297 {
298 // screen width is larger than world's boundary width
299 //set both in the middle of the world
300 rightBoundary = leftBoundary = (leftBoundary + rightBoundary) / 2;
301 }
302 if(topBoundary < bottomBoundary)
303 {
304 // screen width is larger than world's boundary width
305 //set both in the middle of the world
306 topBoundary = bottomBoundary = (topBoundary + bottomBoundary) / 2;
307 }
308
309 if( (topBoundary == bottomBoundary) && (leftBoundary == rightBoundary) )
310 boundaryFullyCovered = TRUE;
311 }
312
313 return self;
314}
315
316-(id) copyWithZone: (NSZone*) zone
317{
318 CCAction *copy = [[[self class] allocWithZone: zone] init];
319 copy.tag = tag_;
320 return copy;
321}
322
323-(void) step:(ccTime) dt
324{
325 if(boundarySet)
326 {
327 // whole map fits inside a single screen, no need to modify the position - unless map boundaries are increased
328 if(boundaryFullyCovered)
329 return;
330
331 CGPoint tempPos = ccpSub( halfScreenSize, followedNode_.position);
332 [target_ setPosition:ccp(clampf(tempPos.x,leftBoundary,rightBoundary), clampf(tempPos.y,bottomBoundary,topBoundary))];
333 }
334 else
335 [target_ setPosition:ccpSub( halfScreenSize, followedNode_.position )];
336
337#undef CLAMP
338}
339
340
341-(BOOL) isDone
342{
343 return !followedNode_.isRunning;
344}
345
346-(void) stop
347{
348 target_ = nil;
349 [super stop];
350}
351
352-(void) dealloc
353{
354 [followedNode_ release];
355 [super dealloc];
356}
357
358@end
359
360