diff options
Diffstat (limited to 'libs/cocos2d/CCAction.m')
-rwxr-xr-x | libs/cocos2d/CCAction.m | 360 |
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 | |||