/libs/cocos2d/CCLayer.m
Objective C | 339 lines | 233 code | 71 blank | 35 comment | 32 complexity | 0739e6c7d0c6aba7244c0b6311f9f606 MD5 | raw file
Possible License(s): Apache-2.0
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 26 27 28#import <OpenGLES/ES1/gl.h> 29#import <stdarg.h> 30 31#import "CCLayer.h" 32#import "CCDirector.h" 33#import "CCTouchDispatcher.h" 34#import "ccMacros.h" 35#import "Support/CGPointExtension.h" 36 37#pragma mark - 38#pragma mark Layer 39 40@implementation CCLayer 41 42#pragma mark Layer - Init 43-(id) init 44{ 45 if( (self=[super init]) ) { 46 47 CGSize s = [[CCDirector sharedDirector] winSize]; 48 anchorPoint_ = ccp(0.5f, 0.5f); 49 [self setContentSize:s]; 50 self.isRelativeAnchorPoint = NO; 51 52 isTouchEnabled = NO; 53 isAccelerometerEnabled = NO; 54 } 55 56 return self; 57} 58 59#pragma mark Layer - Touch and Accelerometer related 60 61-(void) registerWithTouchDispatcher 62{ 63 [[CCTouchDispatcher sharedDispatcher] addStandardDelegate:self priority:0]; 64} 65 66-(BOOL) isAccelerometerEnabled 67{ 68 return isAccelerometerEnabled; 69} 70 71-(void) setIsAccelerometerEnabled:(BOOL)enabled 72{ 73 if( enabled != isAccelerometerEnabled ) { 74 isAccelerometerEnabled = enabled; 75 if( isRunning_ ) { 76 if( enabled ) 77 [[UIAccelerometer sharedAccelerometer] setDelegate:self]; 78 else 79 [[UIAccelerometer sharedAccelerometer] setDelegate:nil]; 80 } 81 } 82} 83 84-(BOOL) isTouchEnabled 85{ 86 return isTouchEnabled; 87} 88 89-(void) setIsTouchEnabled:(BOOL)enabled 90{ 91 if( isTouchEnabled != enabled ) { 92 isTouchEnabled = enabled; 93 if( isRunning_ ) { 94 if( enabled ) 95 [self registerWithTouchDispatcher]; 96 else 97 [[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; 98 } 99 } 100} 101 102#pragma mark Layer - Callbacks 103-(void) onEnter 104{ 105 // register 'parent' nodes first 106 // since events are propagated in reverse order 107 if (isTouchEnabled) 108 [self registerWithTouchDispatcher]; 109 110 // then iterate over all the children 111 [super onEnter]; 112 113 if( isAccelerometerEnabled ) 114 [[UIAccelerometer sharedAccelerometer] setDelegate:self]; 115} 116 117-(void) onExit 118{ 119 if( isTouchEnabled ) 120 [[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; 121 122 if( isAccelerometerEnabled ) 123 [[UIAccelerometer sharedAccelerometer] setDelegate:nil]; 124 125 [super onExit]; 126} 127-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event 128{ 129 NSAssert(NO, @"Layer#ccTouchBegan override me"); 130 return YES; 131} 132@end 133 134#pragma mark - 135#pragma mark ColorLayer 136 137@interface CCColorLayer (Private) 138-(void) updateColor; 139@end 140 141@implementation CCColorLayer 142 143// Opacity and RGB color protocol 144@synthesize opacity=opacity_, color=color_; 145@synthesize blendFunc=blendFunc_; 146 147 148+ (id) layerWithColor:(ccColor4B)color width:(GLfloat)w height:(GLfloat) h 149{ 150 return [[[self alloc] initWithColor:color width:w height:h] autorelease]; 151} 152 153+ (id) layerWithColor:(ccColor4B)color 154{ 155 return [[[self alloc] initWithColor:color] autorelease]; 156} 157 158- (id) initWithColor:(ccColor4B)color width:(GLfloat)w height:(GLfloat) h 159{ 160 if( (self=[super init]) ) { 161 162 // default blend function 163 blendFunc_ = (ccBlendFunc) { CC_BLEND_SRC, CC_BLEND_DST }; 164 165 color_.r = color.r; 166 color_.g = color.g; 167 color_.b = color.b; 168 opacity_ = color.a; 169 170 for (NSUInteger i=0; i<sizeof(squareVertices) / sizeof( squareVertices[0]); i++ ) 171 squareVertices[i] = 0.0f; 172 173 [self updateColor]; 174 [self setContentSize:CGSizeMake(w,h)]; 175 } 176 return self; 177} 178 179- (id) initWithColor:(ccColor4B)color 180{ 181 CGSize s = [[CCDirector sharedDirector] winSize]; 182 return [self initWithColor:color width:s.width height:s.height]; 183} 184 185// override contentSize 186-(void) setContentSize: (CGSize) size 187{ 188 squareVertices[2] = size.width; 189 squareVertices[5] = size.height; 190 squareVertices[6] = size.width; 191 squareVertices[7] = size.height; 192 193 [super setContentSize:size]; 194} 195 196- (void) changeWidth: (GLfloat) w height:(GLfloat) h 197{ 198 [self setContentSize:CGSizeMake(w,h)]; 199} 200 201-(void) changeWidth: (GLfloat) w 202{ 203 [self setContentSize:CGSizeMake(w,contentSize_.height)]; 204} 205 206-(void) changeHeight: (GLfloat) h 207{ 208 [self setContentSize:CGSizeMake(contentSize_.width,h)]; 209} 210 211- (void) updateColor 212{ 213 for( NSUInteger i=0; i < sizeof(squareColors) / sizeof(squareColors[0]);i++ ) 214 { 215 if( i % 4 == 0 ) 216 squareColors[i] = color_.r; 217 else if( i % 4 == 1) 218 squareColors[i] = color_.g; 219 else if( i % 4 ==2 ) 220 squareColors[i] = color_.b; 221 else 222 squareColors[i] = opacity_; 223 } 224} 225 226- (void)draw 227{ 228 // Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY 229 // Needed states: GL_VERTEX_ARRAY, GL_COLOR_ARRAY 230 // Unneeded states: GL_TEXTURE_2D, GL_TEXTURE_COORD_ARRAY 231 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 232 glDisable(GL_TEXTURE_2D); 233 234 glVertexPointer(2, GL_FLOAT, 0, squareVertices); 235 glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors); 236 237 BOOL newBlend = NO; 238 if( blendFunc_.src != CC_BLEND_SRC || blendFunc_.dst != CC_BLEND_DST ) { 239 newBlend = YES; 240 glBlendFunc(blendFunc_.src, blendFunc_.dst); 241 } 242 else if( opacity_ != 255 ) { 243 newBlend = YES; 244 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 245 } 246 247 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 248 249 if( newBlend ) 250 glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST); 251 252 // restore default GL state 253 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 254 glEnable(GL_TEXTURE_2D); 255} 256 257#pragma mark Protocols 258// Color Protocol 259 260-(void) setColor:(ccColor3B)color 261{ 262 color_ = color; 263 [self updateColor]; 264} 265 266-(void) setOpacity: (GLubyte) o 267{ 268 opacity_ = o; 269 [self updateColor]; 270} 271@end 272 273#pragma mark - 274#pragma mark MultiplexLayer 275 276@implementation CCMultiplexLayer 277+(id) layerWithLayers: (CCLayer*) layer, ... 278{ 279 va_list args; 280 va_start(args,layer); 281 282 id s = [[[self alloc] initWithLayers: layer vaList:args] autorelease]; 283 284 va_end(args); 285 return s; 286} 287 288-(id) initWithLayers: (CCLayer*) layer vaList:(va_list) params 289{ 290 if( (self=[super init]) ) { 291 292 layers = [[NSMutableArray arrayWithCapacity:5] retain]; 293 294 [layers addObject: layer]; 295 296 CCLayer *l = va_arg(params,CCLayer*); 297 while( l ) { 298 [layers addObject: l]; 299 l = va_arg(params,CCLayer*); 300 } 301 302 enabledLayer = 0; 303 [self addChild: [layers objectAtIndex: enabledLayer]]; 304 } 305 306 return self; 307} 308 309-(void) dealloc 310{ 311 [layers release]; 312 [super dealloc]; 313} 314 315-(void) switchTo: (unsigned int) n 316{ 317 NSAssert( n < [layers count], @"Invalid index in MultiplexLayer switchTo message" ); 318 319 [self removeChild: [layers objectAtIndex:enabledLayer] cleanup:YES]; 320 321 enabledLayer = n; 322 323 [self addChild: [layers objectAtIndex:n]]; 324} 325 326-(void) switchToAndReleaseMe: (unsigned int) n 327{ 328 NSAssert( n < [layers count], @"Invalid index in MultiplexLayer switchTo message" ); 329 330 [self removeChild: [layers objectAtIndex:enabledLayer] cleanup:YES]; 331 332 [layers replaceObjectAtIndex:enabledLayer withObject:[NSNull null]]; 333 334 enabledLayer = n; 335 336 [self addChild: [layers objectAtIndex:n]]; 337} 338 339@end