/libs/cocos2d/CCLayer.m

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