summary refs log tree commit diff stats
path: root/libs/cocos2d/CCLayer.m
diff options
context:
space:
mode:
Diffstat (limited to 'libs/cocos2d/CCLayer.m')
-rwxr-xr-xlibs/cocos2d/CCLayer.m621
1 files changed, 621 insertions, 0 deletions
diff --git a/libs/cocos2d/CCLayer.m b/libs/cocos2d/CCLayer.m new file mode 100755 index 0000000..fe5a72d --- /dev/null +++ b/libs/cocos2d/CCLayer.m
@@ -0,0 +1,621 @@
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#import <stdarg.h>
29
30#import "Platforms/CCGL.h"
31
32#import "CCLayer.h"
33#import "CCDirector.h"
34#import "ccMacros.h"
35#import "Support/CGPointExtension.h"
36
37#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
38#import "Platforms/iOS/CCTouchDispatcher.h"
39#import "Platforms/iOS/CCDirectorIOS.h"
40#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
41#import "Platforms/Mac/CCEventDispatcher.h"
42#endif
43
44#pragma mark -
45#pragma mark Layer
46
47@implementation CCLayer
48
49#pragma mark Layer - Init
50-(id) init
51{
52 if( (self=[super init]) ) {
53
54 CGSize s = [[CCDirector sharedDirector] winSize];
55 anchorPoint_ = ccp(0.5f, 0.5f);
56 [self setContentSize:s];
57 self.isRelativeAnchorPoint = NO;
58
59 isTouchEnabled_ = NO;
60
61#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
62 isAccelerometerEnabled_ = NO;
63#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
64 isMouseEnabled_ = NO;
65 isKeyboardEnabled_ = NO;
66#endif
67 }
68
69 return self;
70}
71
72#pragma mark Layer - Touch and Accelerometer related
73
74#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
75-(void) registerWithTouchDispatcher
76{
77 [[CCTouchDispatcher sharedDispatcher] addStandardDelegate:self priority:0];
78}
79
80-(BOOL) isAccelerometerEnabled
81{
82 return isAccelerometerEnabled_;
83}
84
85-(void) setIsAccelerometerEnabled:(BOOL)enabled
86{
87 if( enabled != isAccelerometerEnabled_ ) {
88 isAccelerometerEnabled_ = enabled;
89 if( isRunning_ ) {
90 if( enabled )
91 [[UIAccelerometer sharedAccelerometer] setDelegate:self];
92 else
93 [[UIAccelerometer sharedAccelerometer] setDelegate:nil];
94 }
95 }
96}
97
98-(BOOL) isTouchEnabled
99{
100 return isTouchEnabled_;
101}
102
103-(void) setIsTouchEnabled:(BOOL)enabled
104{
105 if( isTouchEnabled_ != enabled ) {
106 isTouchEnabled_ = enabled;
107 if( isRunning_ ) {
108 if( enabled )
109 [self registerWithTouchDispatcher];
110 else
111 [[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
112 }
113 }
114}
115
116#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
117
118#pragma mark CCLayer - Mouse, Keyboard & Touch events
119
120-(NSInteger) mouseDelegatePriority
121{
122 return 0;
123}
124
125-(BOOL) isMouseEnabled
126{
127 return isMouseEnabled_;
128}
129
130-(void) setIsMouseEnabled:(BOOL)enabled
131{
132 if( isMouseEnabled_ != enabled ) {
133 isMouseEnabled_ = enabled;
134
135 if( isRunning_ ) {
136 if( enabled )
137 [[CCEventDispatcher sharedDispatcher] addMouseDelegate:self priority:[self mouseDelegatePriority]];
138 else
139 [[CCEventDispatcher sharedDispatcher] removeMouseDelegate:self];
140 }
141 }
142}
143
144-(NSInteger) keyboardDelegatePriority
145{
146 return 0;
147}
148
149-(BOOL) isKeyboardEnabled
150{
151 return isKeyboardEnabled_;
152}
153
154-(void) setIsKeyboardEnabled:(BOOL)enabled
155{
156 if( isKeyboardEnabled_ != enabled ) {
157 isKeyboardEnabled_ = enabled;
158
159 if( isRunning_ ) {
160 if( enabled )
161 [[CCEventDispatcher sharedDispatcher] addKeyboardDelegate:self priority:[self keyboardDelegatePriority] ];
162 else
163 [[CCEventDispatcher sharedDispatcher] removeKeyboardDelegate:self];
164 }
165 }
166}
167
168-(NSInteger) touchDelegatePriority
169{
170 return 0;
171}
172
173-(BOOL) isTouchEnabled
174{
175 return isTouchEnabled_;
176}
177
178-(void) setIsTouchEnabled:(BOOL)enabled
179{
180 if( isTouchEnabled_ != enabled ) {
181 isTouchEnabled_ = enabled;
182 if( isRunning_ ) {
183 if( enabled )
184 [[CCEventDispatcher sharedDispatcher] addTouchDelegate:self priority:[self touchDelegatePriority]];
185 else
186 [[CCEventDispatcher sharedDispatcher] removeTouchDelegate:self];
187 }
188 }
189}
190
191
192#endif // Mac
193
194
195#pragma mark Layer - Callbacks
196-(void) onEnter
197{
198#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
199 // register 'parent' nodes first
200 // since events are propagated in reverse order
201 if (isTouchEnabled_)
202 [self registerWithTouchDispatcher];
203
204#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
205 if( isMouseEnabled_ )
206 [[CCEventDispatcher sharedDispatcher] addMouseDelegate:self priority:[self mouseDelegatePriority]];
207
208 if( isKeyboardEnabled_)
209 [[CCEventDispatcher sharedDispatcher] addKeyboardDelegate:self priority:[self keyboardDelegatePriority]];
210
211 if( isTouchEnabled_)
212 [[CCEventDispatcher sharedDispatcher] addTouchDelegate:self priority:[self touchDelegatePriority]];
213
214#endif
215
216 // then iterate over all the children
217 [super onEnter];
218}
219
220// issue #624.
221// Can't register mouse, touches here because of #issue #1018, and #1021
222-(void) onEnterTransitionDidFinish
223{
224#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
225 if( isAccelerometerEnabled_ )
226 [[UIAccelerometer sharedAccelerometer] setDelegate:self];
227#endif
228
229 [super onEnterTransitionDidFinish];
230}
231
232
233-(void) onExit
234{
235#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
236 if( isTouchEnabled_ )
237 [[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
238
239 if( isAccelerometerEnabled_ )
240 [[UIAccelerometer sharedAccelerometer] setDelegate:nil];
241
242#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
243 if( isMouseEnabled_ )
244 [[CCEventDispatcher sharedDispatcher] removeMouseDelegate:self];
245
246 if( isKeyboardEnabled_ )
247 [[CCEventDispatcher sharedDispatcher] removeKeyboardDelegate:self];
248
249 if( isTouchEnabled_ )
250 [[CCEventDispatcher sharedDispatcher] removeTouchDelegate:self];
251
252#endif
253
254 [super onExit];
255}
256
257#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
258-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
259{
260 NSAssert(NO, @"Layer#ccTouchBegan override me");
261 return YES;
262}
263#endif
264@end
265
266#pragma mark -
267#pragma mark LayerColor
268
269@interface CCLayerColor (Private)
270-(void) updateColor;
271@end
272
273@implementation CCLayerColor
274
275// Opacity and RGB color protocol
276@synthesize opacity = opacity_, color = color_;
277@synthesize blendFunc = blendFunc_;
278
279
280+ (id) layerWithColor:(ccColor4B)color width:(GLfloat)w height:(GLfloat) h
281{
282 return [[[self alloc] initWithColor:color width:w height:h] autorelease];
283}
284
285+ (id) layerWithColor:(ccColor4B)color
286{
287 return [[(CCLayerColor*)[self alloc] initWithColor:color] autorelease];
288}
289
290- (id) initWithColor:(ccColor4B)color width:(GLfloat)w height:(GLfloat) h
291{
292 if( (self=[super init]) ) {
293
294 // default blend function
295 blendFunc_ = (ccBlendFunc) { CC_BLEND_SRC, CC_BLEND_DST };
296
297 color_.r = color.r;
298 color_.g = color.g;
299 color_.b = color.b;
300 opacity_ = color.a;
301
302 for (NSUInteger i = 0; i<sizeof(squareVertices_) / sizeof( squareVertices_[0]); i++ ) {
303 squareVertices_[i].x = 0.0f;
304 squareVertices_[i].y = 0.0f;
305 }
306
307 [self updateColor];
308 [self setContentSize:CGSizeMake(w, h) ];
309 }
310 return self;
311}
312
313- (id) initWithColor:(ccColor4B)color
314{
315 CGSize s = [[CCDirector sharedDirector] winSize];
316 return [self initWithColor:color width:s.width height:s.height];
317}
318
319// override contentSize
320-(void) setContentSize: (CGSize) size
321{
322 squareVertices_[1].x = size.width * CC_CONTENT_SCALE_FACTOR();
323 squareVertices_[2].y = size.height * CC_CONTENT_SCALE_FACTOR();
324 squareVertices_[3].x = size.width * CC_CONTENT_SCALE_FACTOR();
325 squareVertices_[3].y = size.height * CC_CONTENT_SCALE_FACTOR();
326
327 [super setContentSize:size];
328}
329
330- (void) changeWidth: (GLfloat) w height:(GLfloat) h
331{
332 [self setContentSize:CGSizeMake(w, h)];
333}
334
335-(void) changeWidth: (GLfloat) w
336{
337 [self setContentSize:CGSizeMake(w, contentSize_.height)];
338}
339
340-(void) changeHeight: (GLfloat) h
341{
342 [self setContentSize:CGSizeMake(contentSize_.width, h)];
343}
344
345- (void) updateColor
346{
347 for( NSUInteger i = 0; i < 4; i++ )
348 {
349 squareColors_[i].r = color_.r;
350 squareColors_[i].g = color_.g;
351 squareColors_[i].b = color_.b;
352 squareColors_[i].a = opacity_;
353 }
354}
355
356- (void)draw
357{
358 [super draw];
359
360 // Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
361 // Needed states: GL_VERTEX_ARRAY, GL_COLOR_ARRAY
362 // Unneeded states: GL_TEXTURE_2D, GL_TEXTURE_COORD_ARRAY
363 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
364 glDisable(GL_TEXTURE_2D);
365
366 glVertexPointer(2, GL_FLOAT, 0, squareVertices_);
367 glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors_);
368
369
370 BOOL newBlend = blendFunc_.src != CC_BLEND_SRC || blendFunc_.dst != CC_BLEND_DST;
371 if( newBlend )
372 glBlendFunc( blendFunc_.src, blendFunc_.dst );
373
374 else if( opacity_ != 255 ) {
375 newBlend = YES;
376 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
377 }
378
379 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
380
381 if( newBlend )
382 glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
383
384 // restore default GL state
385 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
386 glEnable(GL_TEXTURE_2D);
387}
388
389#pragma mark Protocols
390// Color Protocol
391
392-(void) setColor:(ccColor3B)color
393{
394 color_ = color;
395 [self updateColor];
396}
397
398-(void) setOpacity: (GLubyte) o
399{
400 opacity_ = o;
401 [self updateColor];
402}
403@end
404
405// XXX Deprecated
406@implementation CCColorLayer
407@end
408
409
410#pragma mark -
411#pragma mark LayerGradient
412
413@implementation CCLayerGradient
414
415@synthesize startOpacity = startOpacity_;
416@synthesize endColor = endColor_, endOpacity = endOpacity_;
417@synthesize vector = vector_;
418
419+ (id) layerWithColor: (ccColor4B) start fadingTo: (ccColor4B) end
420{
421 return [[[self alloc] initWithColor:start fadingTo:end] autorelease];
422}
423
424+ (id) layerWithColor: (ccColor4B) start fadingTo: (ccColor4B) end alongVector: (CGPoint) v
425{
426 return [[[self alloc] initWithColor:start fadingTo:end alongVector:v] autorelease];
427}
428
429- (id) initWithColor: (ccColor4B) start fadingTo: (ccColor4B) end
430{
431 return [self initWithColor:start fadingTo:end alongVector:ccp(0, -1)];
432}
433
434- (id) initWithColor: (ccColor4B) start fadingTo: (ccColor4B) end alongVector: (CGPoint) v
435{
436 endColor_.r = end.r;
437 endColor_.g = end.g;
438 endColor_.b = end.b;
439
440 endOpacity_ = end.a;
441 startOpacity_ = start.a;
442 vector_ = v;
443
444 start.a = 255;
445 compressedInterpolation_ = YES;
446
447 return [super initWithColor:start];
448}
449
450- (void) updateColor
451{
452 [super updateColor];
453
454 float h = ccpLength(vector_);
455 if (h == 0)
456 return;
457
458 double c = sqrt(2);
459 CGPoint u = ccp(vector_.x / h, vector_.y / h);
460
461 // Compressed Interpolation mode
462 if( compressedInterpolation_ ) {
463 float h2 = 1 / ( fabsf(u.x) + fabsf(u.y) );
464 u = ccpMult(u, h2 * (float)c);
465 }
466
467 float opacityf = (float)opacity_/255.0f;
468
469 ccColor4B S = {
470 color_.r,
471 color_.g,
472 color_.b,
473 startOpacity_*opacityf
474 };
475
476 ccColor4B E = {
477 endColor_.r,
478 endColor_.g,
479 endColor_.b,
480 endOpacity_*opacityf
481 };
482
483
484 // (-1, -1)
485 squareColors_[0].r = E.r + (S.r - E.r) * ((c + u.x + u.y) / (2.0f * c));
486 squareColors_[0].g = E.g + (S.g - E.g) * ((c + u.x + u.y) / (2.0f * c));
487 squareColors_[0].b = E.b + (S.b - E.b) * ((c + u.x + u.y) / (2.0f * c));
488 squareColors_[0].a = E.a + (S.a - E.a) * ((c + u.x + u.y) / (2.0f * c));
489 // (1, -1)
490 squareColors_[1].r = E.r + (S.r - E.r) * ((c - u.x + u.y) / (2.0f * c));
491 squareColors_[1].g = E.g + (S.g - E.g) * ((c - u.x + u.y) / (2.0f * c));
492 squareColors_[1].b = E.b + (S.b - E.b) * ((c - u.x + u.y) / (2.0f * c));
493 squareColors_[1].a = E.a + (S.a - E.a) * ((c - u.x + u.y) / (2.0f * c));
494 // (-1, 1)
495 squareColors_[2].r = E.r + (S.r - E.r) * ((c + u.x - u.y) / (2.0f * c));
496 squareColors_[2].g = E.g + (S.g - E.g) * ((c + u.x - u.y) / (2.0f * c));
497 squareColors_[2].b = E.b + (S.b - E.b) * ((c + u.x - u.y) / (2.0f * c));
498 squareColors_[2].a = E.a + (S.a - E.a) * ((c + u.x - u.y) / (2.0f * c));
499 // (1, 1)
500 squareColors_[3].r = E.r + (S.r - E.r) * ((c - u.x - u.y) / (2.0f * c));
501 squareColors_[3].g = E.g + (S.g - E.g) * ((c - u.x - u.y) / (2.0f * c));
502 squareColors_[3].b = E.b + (S.b - E.b) * ((c - u.x - u.y) / (2.0f * c));
503 squareColors_[3].a = E.a + (S.a - E.a) * ((c - u.x - u.y) / (2.0f * c));
504}
505
506-(ccColor3B) startColor
507{
508 return color_;
509}
510
511-(void) setStartColor:(ccColor3B)colors
512{
513 [self setColor:colors];
514}
515
516-(void) setEndColor:(ccColor3B)colors
517{
518 endColor_ = colors;
519 [self updateColor];
520}
521
522-(void) setStartOpacity: (GLubyte) o
523{
524 startOpacity_ = o;
525 [self updateColor];
526}
527
528-(void) setEndOpacity: (GLubyte) o
529{
530 endOpacity_ = o;
531 [self updateColor];
532}
533
534-(void) setVector: (CGPoint) v
535{
536 vector_ = v;
537 [self updateColor];
538}
539
540-(BOOL) compressedInterpolation
541{
542 return compressedInterpolation_;
543}
544
545-(void) setCompressedInterpolation:(BOOL)compress
546{
547 compressedInterpolation_ = compress;
548 [self updateColor];
549}
550@end
551
552#pragma mark -
553#pragma mark MultiplexLayer
554
555@implementation CCLayerMultiplex
556+(id) layerWithLayers: (CCLayer*) layer, ...
557{
558 va_list args;
559 va_start(args,layer);
560
561 id s = [[[self alloc] initWithLayers: layer vaList:args] autorelease];
562
563 va_end(args);
564 return s;
565}
566
567-(id) initWithLayers: (CCLayer*) layer vaList:(va_list) params
568{
569 if( (self=[super init]) ) {
570
571 layers_ = [[NSMutableArray arrayWithCapacity:5] retain];
572
573 [layers_ addObject: layer];
574
575 CCLayer *l = va_arg(params,CCLayer*);
576 while( l ) {
577 [layers_ addObject: l];
578 l = va_arg(params,CCLayer*);
579 }
580
581 enabledLayer_ = 0;
582 [self addChild: [layers_ objectAtIndex: enabledLayer_]];
583 }
584
585 return self;
586}
587
588-(void) dealloc
589{
590 [layers_ release];
591 [super dealloc];
592}
593
594-(void) switchTo: (unsigned int) n
595{
596 NSAssert( n < [layers_ count], @"Invalid index in MultiplexLayer switchTo message" );
597
598 [self removeChild: [layers_ objectAtIndex:enabledLayer_] cleanup:YES];
599
600 enabledLayer_ = n;
601
602 [self addChild: [layers_ objectAtIndex:n]];
603}
604
605-(void) switchToAndReleaseMe: (unsigned int) n
606{
607 NSAssert( n < [layers_ count], @"Invalid index in MultiplexLayer switchTo message" );
608
609 [self removeChild: [layers_ objectAtIndex:enabledLayer_] cleanup:YES];
610
611 [layers_ replaceObjectAtIndex:enabledLayer_ withObject:[NSNull null]];
612
613 enabledLayer_ = n;
614
615 [self addChild: [layers_ objectAtIndex:n]];
616}
617@end
618
619// XXX Deprecated
620@implementation CCMultiplexLayer
621@end