Advertisement
Guest User

Untitled

a guest
Aug 19th, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.65 KB | None | 0 0
  1. #pragma mark update
  2.  
  3. -(void) update:(ccTime)delta
  4. {
  5. // Keep adding up the playerVelocity to the player's position
  6.  
  7. // This requires a temporary variable because you can't modify player.position.x directly. Objective-C properties
  8. // work a little different than what you may be used to from other languages. The problem is that player.position
  9. // actually is a method call [player position] and you simply can't change a member ".x" of that method. In other words,
  10. // you can't change members of struct properties like CGPoint, CGRect, CGSize directly through a property getter method.
  11. CGPoint pos = player.position;
  12. pos.x += playerVelocity.x;
  13.  
  14. // Alternatively you could re-write the above 3 lines as follows. I find the above more readable however.
  15. // player.position = CGPointMake(player.position.x + playerVelocity.x, player.position.y);
  16.  
  17. // The seemingly obvious alternative won't work in Objective-C! It'll give you the following error.
  18. // ERROR: lvalue required as left operand of assignment
  19. // player.position.x += playerVelocity.x;
  20.  
  21. // The Player should also be stopped from going outside the screen
  22. CGSize screenSize = [[CCDirector sharedDirector] winSize];
  23. float imageWidthHalved = [player texture].contentSize.width * 0.5f;
  24. float leftBorderLimit = imageWidthHalved;
  25. float rightBorderLimit = screenSize.width - imageWidthHalved;
  26.  
  27. // the left/right border check is performed against half the player image's size so that the sides of the actual
  28. // sprite are blocked from going outside the screen because the player sprite's position is at the center of the image
  29. if (pos.x < leftBorderLimit)
  30. {
  31. pos.x = leftBorderLimit;
  32.  
  33. // also set velocity to zero because the player is still accelerating towards the border
  34. playerVelocity = CGPointZero;
  35. }
  36. else if (pos.x > rightBorderLimit)
  37. {
  38. pos.x = rightBorderLimit;
  39.  
  40. // also set velocity to zero because the player is still accelerating towards the border
  41. playerVelocity = CGPointZero;
  42. }
  43.  
  44. // Alternatively, the above if/else if block can be rewritten using fminf and fmaxf more neatly like so:
  45. // pos.x = fmaxf(fminf(pos.x, rightBorderLimit), leftBorderLimit);
  46.  
  47. player.position = pos;
  48.  
  49. // Do the collision checks
  50. [self checkForCollision];
  51.  
  52. // Update the Score (Timer) once per second. If you'd do it more often, especially every frame, this
  53. // will easily drag the framerate down. Updating a CCLabel's strings is slow!
  54. totalTime += delta;
  55. int currentTime = (int)totalTime;
  56. if (score < currentTime)
  57. {
  58. score = currentTime;
  59. [scoreLabel setString:[NSString stringWithFormat:@"%i", score]];
  60. }
  61. }
  62.  
  63. #pragma mark Collision Checks
  64.  
  65. -(void) checkForCollision
  66. {
  67. // Assumption: both player and spider images are squares.
  68. float playerImageSize = [player texture].contentSize.width;
  69. float spiderImageSize = [[spiders lastObject] texture].contentSize.width;
  70. // If you adjust the factors make sure you also change them in the -(void) draw method.
  71. float playerCollisionRadius = playerImageSize * 0.4f;
  72. float spiderCollisionRadius = spiderImageSize * 0.4f;
  73.  
  74. // This collision distance will roughly equal the image shapes.
  75. float maxCollisionDistance = playerCollisionRadius + spiderCollisionRadius;
  76.  
  77. // Cache [spiders count] for the duration of the loop to avoid repetitive and unnecessary calls to [spiders count].
  78. int numSpiders = [spiders count];
  79. for (int i = 0; i < numSpiders; i++)
  80. {
  81. CCSprite* spider = [spiders objectAtIndex:i];
  82.  
  83. if ([spider numberOfRunningActions] == 0)
  84. {
  85. // This spider isn't even moving so we can skip checking it.
  86. continue;
  87. }
  88.  
  89. // Get the distance between player and spider. Here's where it's great that the images are centered
  90. // on the node positions, you don't need to take into account any offsets which you would have if the
  91. // position would coincide with the image's lower left corner for example.
  92. float actualDistance = ccpDistance(player.position, spider.position);
  93.  
  94. // Are the two objects closer than allowed?
  95. if (actualDistance < maxCollisionDistance)
  96. {
  97. [[SimpleAudioEngine sharedEngine] playEffect:@"alien-sfx.caf"];
  98.  
  99. // No game over yet, just reset the game.
  100. [self showGameOver];
  101. }
  102. }
  103. }
  104.  
  105. #pragma mark Reset Game
  106. // The game is played only using the accelerometer. The screen may go dark while playing because the player
  107. // won't touch the screen. This method allows the screensaver to be disabled during gameplay.
  108. -(void) setScreenSaverEnabled:(bool)enabled
  109. {
  110. UIApplication *thisApp = [UIApplication sharedApplication];
  111. thisApp.idleTimerDisabled = !enabled;
  112. }
  113.  
  114. -(void) showGameOver
  115. {
  116. // Re-enable screensaver, to prevent battery drain in case the user puts the device aside without turning it off.
  117. [self setScreenSaverEnabled:YES];
  118.  
  119. // have everything stop
  120. CCNode* node;
  121. CCARRAY_FOREACH([self children], node)
  122. {
  123. [node stopAllActions];
  124. }
  125.  
  126. // I do want the spiders to keep wiggling so I simply restart this here
  127. CCSprite* spider;
  128. CCARRAY_FOREACH(spiders, spider)
  129. {
  130. [self runSpiderWiggleSequence:spider];
  131. }
  132.  
  133. // disable accelerometer input for the time being
  134. self.isAccelerometerEnabled = NO;
  135. // but allow touch input now
  136. self.isTouchEnabled = YES;
  137.  
  138. // stop the scheduled selectors
  139. [self unscheduleAllSelectors];
  140.  
  141. // add the labels shown during game over
  142. CGSize screenSize = [[CCDirector sharedDirector] winSize];
  143.  
  144. CCLabel* gameOver = [CCLabel labelWithString:@"GAME OVER!" fontName:@"Marker Felt" fontSize:60];
  145. gameOver.position = CGPointMake(screenSize.width / 2, screenSize.height / 3);
  146. [self addChild:gameOver z:100 tag:100];
  147.  
  148. // game over label runs 3 different actions at the same time to create the combined effect
  149. // 1) color tinting
  150. CCTintTo* tint1 = [CCTintTo actionWithDuration:2 red:255 green:0 blue:0];
  151. CCTintTo* tint2 = [CCTintTo actionWithDuration:2 red:255 green:255 blue:0];
  152. CCTintTo* tint3 = [CCTintTo actionWithDuration:2 red:0 green:255 blue:0];
  153. CCTintTo* tint4 = [CCTintTo actionWithDuration:2 red:0 green:255 blue:255];
  154. CCTintTo* tint5 = [CCTintTo actionWithDuration:2 red:0 green:0 blue:255];
  155. CCTintTo* tint6 = [CCTintTo actionWithDuration:2 red:255 green:0 blue:255];
  156. CCSequence* tintSequence = [CCSequence actions:tint1, tint2, tint3, tint4, tint5, tint6, nil];
  157. CCRepeatForever* repeatTint = [CCRepeatForever actionWithAction:tintSequence];
  158. [gameOver runAction:repeatTint];
  159.  
  160. // 2) rotation with ease
  161. CCRotateTo* rotate1 = [CCRotateTo actionWithDuration:2 angle:3];
  162. CCEaseBounceInOut* bounce1 = [CCEaseBounceInOut actionWithAction:rotate1];
  163. CCRotateTo* rotate2 = [CCRotateTo actionWithDuration:2 angle:-3];
  164. CCEaseBounceInOut* bounce2 = [CCEaseBounceInOut actionWithAction:rotate2];
  165. CCSequence* rotateSequence = [CCSequence actions:bounce1, bounce2, nil];
  166. CCRepeatForever* repeatBounce = [CCRepeatForever actionWithAction:rotateSequence];
  167. [gameOver runAction:repeatBounce];
  168.  
  169. // 3) jumping
  170. CCJumpBy* jump = [CCJumpBy actionWithDuration:3 position:CGPointZero height:screenSize.height / 3 jumps:1];
  171. CCRepeatForever* repeatJump = [CCRepeatForever actionWithAction:jump];
  172. [gameOver runAction:repeatJump];
  173.  
  174. // touch to continue label
  175. CCLabel* touch = [CCLabel labelWithString:@"tap screen to play again" fontName:@"Arial" fontSize:20];
  176. touch.position = CGPointMake(screenSize.width / 2, screenSize.height / 4);
  177. [self addChild:touch z:100 tag:101];
  178.  
  179. // did you try turning it off and on again?
  180. CCBlink* blink = [CCBlink actionWithDuration:10 blinks:20];
  181. CCRepeatForever* repeatBlink = [CCRepeatForever actionWithAction:blink];
  182. [touch runAction:repeatBlink];
  183. }
  184.  
  185.  
  186. -(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
  187. {
  188. [self resetGame];
  189. }
  190.  
  191. -(void) resetGame
  192. {
  193. // prevent screensaver from darkening the screen while the game is played
  194. [self setScreenSaverEnabled:NO];
  195.  
  196. // remove game over label & touch to continue label
  197. [self removeChildByTag:100 cleanup:YES];
  198. [self removeChildByTag:101 cleanup:YES];
  199.  
  200. // re-enable accelerometer
  201. self.isAccelerometerEnabled = YES;
  202. self.isTouchEnabled = NO;
  203.  
  204. // put all spiders back to top
  205. [self resetSpiders];
  206.  
  207. // re-schedule update
  208. [self scheduleUpdate];
  209.  
  210. // reset score
  211. score = 0;
  212. totalTime = 0;
  213. [scoreLabel setString:@"0"];
  214. }
  215.  
  216. // Only draw this debugging information in, well, debug builds.
  217. -(void) draw
  218. {
  219. #if DEBUG
  220. // Iterate through all nodes of the layer.
  221. CCNode* node;
  222. CCARRAY_FOREACH([self children], node)
  223. {
  224. // Make sure the node is a CCSprite and has the right tags.
  225. if ([node isKindOfClass:[CCSprite class]] && (node.tag == 1 || node.tag == 2))
  226. {
  227. // The sprite's collision radius is a percentage of its image width. Use that to draw a circle
  228. // which represents the sprite's collision radius.
  229. CCSprite* sprite = (CCSprite*)node;
  230. float radius = [sprite texture].contentSize.width * 0.4f;
  231. float angle = 0;
  232. int numSegments = 10;
  233. bool drawLineToCenter = NO;
  234. ccDrawCircle(sprite.position, radius, angle, numSegments, drawLineToCenter);
  235. }
  236. }
  237. #endif
  238.  
  239. CGSize screenSize = [[CCDirector sharedDirector] winSize];
  240.  
  241. // always keep variables you have to calculate only once outside the loop
  242. float threadCutPosition = screenSize.height * 0.75f;
  243.  
  244. // Draw a spider thread using OpenGL
  245. // CCARRAY_FOREACH is a bit faster than regular for loop
  246. CCSprite* spider;
  247. CCARRAY_FOREACH(spiders, spider)
  248. {
  249. // only draw thread up to a certain point
  250. if (spider.position.y > threadCutPosition)
  251. {
  252. // vary thread position a little so it looks a bit more dynamic
  253. float threadX = spider.position.x + (CCRANDOM_0_1() * 2.0f - 1.0f);
  254.  
  255. glColor4f(0.5f, 0.5f, 0.5f, 1.0f);
  256. ccDrawLine(spider.position, CGPointMake(threadX, screenSize.height));
  257. }
  258. }
  259. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement