{"id":2759,"date":"2011-12-22T14:18:46","date_gmt":"2011-12-22T19:18:46","guid":{"rendered":"http:\/\/www.lonhosford.com\/lonblog\/?p=2759"},"modified":"2015-07-31T18:25:49","modified_gmt":"2015-07-31T23:25:49","slug":"kobold2d-xcode-4-introduction-tutorial-lesson-5-add-collision-detection","status":"publish","type":"post","link":"https:\/\/www.lonhosford.com\/lonblog\/2011\/12\/22\/kobold2d-xcode-4-introduction-tutorial-lesson-5-add-collision-detection\/","title":{"rendered":"Kobold2D XCode 4 Introduction Tutorial Lesson 5 &#8211; Add Collision Detection"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p><script src=\"https:\/\/connect.facebook.net\/en_US\/all.js#appId=105467682877384&amp;xfbml=1\"><\/script><fb:like href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/12\/18\/kobold2d-xcode-4-introduction-tutorial-lesson-1-basic-accelerometer\/\" send=\"true\" width=\"450\" show_faces=\"true\" font=\"\"><\/fb:like><!-- Place this tag where you want the +1 button to render --><br \/>\n<g:plusone annotation=\"inline\"><\/g:plusone><\/p>\n<p><a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/12\/21\/kobold2d-xcode-4-introduction-tutorial-lesson-4-progressively-increase-moving-target-speed\/\">&lt;== Lesson 4<\/a> || <a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/12\/23\/kobold2d-xcode-4-introduction-tutorial-lesson-6-add-collision-sound-effect\/\">Lesson 6 ==&gt; <\/a>  <\/p>\n<p>Now its time to detect the collision of the moving target and the player. <img loading=\"lazy\" decoding=\"async\" class=\"alignleft\" src=\"https:\/\/www.lonhosford.com\/images\/kobold2d\/common\/blog_article.png\" alt=\"\" width=\"160\" height=\"218\" \/><br \/>\n<figure style=\"width: 121px\" class=\"wp-caption alignright\"><a href=\"http:\/\/www.amazon.com\/gp\/product\/1430238135\/ref=as_li_ss_tl?ie=UTF8&#038;tag=hosfordusa&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=1430238135\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\"  src=\"https:\/\/images-na.ssl-images-amazon.com\/images\/I\/415NHKs30yL._SL160_.jpg\" alt=\"Learn cocos2D Game Development\" width=\"121\" height=\"160\" class=\"  \" title=\"Learn cocos2D Game Development\"\/><\/a><figcaption class=\"wp-caption-text\">Learn cocos2D Game Development<\/figcaption><\/figure> <\/p>\n<p>For this game, the collision is a good thing as that is the goal. So we will call collisions between the player and the moving target a hit. <\/p>\n<p>To plan ahead, you will also add a counter to detect the number of hits. For now you will just display that value in the XCode console window.  That will help debug the collision detection and set up for use of that value.<\/p>\n<figure style=\"width: 550px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\" \" style=\"border: 0pt none;\" src=\"https:\/\/www.lonhosford.com\/images\/kobold2d\/lesson_05\/ipad_running.png\" alt=\"\" width=\"550\" height=\"423\" \/><figcaption class=\"wp-caption-text\">Finished Lesson Running on IPad2 Simulator<\/figcaption><\/figure>\n<p><strong>Lesson Downloads<\/strong><\/p>\n<ol>\n<li>\n<a onclick=\"javascript: pageTracker._trackPageview('\/downloads\/kobold2d\/intro_tutorial\/lesson05\/introduction_tutorial_lesson05_images.zip'); \" href=\"https:\/\/www.lonhosford.com\/content\/kobold2d\/intro_tutorial\/lesson05\/introduction_tutorial_lesson05_images.zip\">Game piece images for project<\/a><\/li>\n<li>\n<a onclick=\"javascript: pageTracker._trackPageview('\/downloads\/kobold2d\/intro_tutorial\/lesson05\/introduction_tutorial_common.zip'); \" href=\"https:\/\/www.lonhosford.com\/content\/kobold2d\/intro_tutorial\/lesson05\/introduction_tutorial_common.zip\">IPhone images for project<\/a>. Icons and splash screen.<\/li>\n<li>\n<a onclick=\"javascript: pageTracker._trackPageview('\/downloads\/kobold2d\/intro_tutorial\/lesson05\/Intro_Tutorial_Lesson_05.zip'); \" href=\"https:\/\/www.lonhosford.com\/content\/kobold2d\/intro_tutorial\/lesson05\/Intro_Tutorial_Lesson_05.zip\">Completed Project<\/a>. This is built in Kobold2d 1.0.1.<\/li>\n<\/ol>\n<p><strong>Step 1 &#8211; Build an Empty-Project Template<\/strong><\/p>\n<p>You can continue with the <a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/12\/21\/kobold2d-xcode-4-introduction-tutorial-lesson-4-progressively-increase-moving-target-speed\/\">Lesson 4<\/a> project and make changes noted here. Otherwise the steps for creating this project from an Empty-Project template are the same as <a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/12\/18\/kobold2d-xcode-4-introduction-tutorial-lesson-1-basic-accelerometer\/\">Lesson 1<\/a> except to substitute Lesson 5 for Lesson 1 in the project name and to include the red_ball.png and red_ball-hd.png files when you add the game pieces. Then you can use the code presented here.<br \/>\n[ad name=&#8221;Google Adsense&#8221;]<\/p>\n<p><strong>Step 2 &#8211; Set Properties in config.lua<\/strong><\/p>\n<p>There are no new configuration properties from Lesson 4. Complete config.lua file is included here for your copy convenience.<\/p>\n<pre class=\"brush: jscript; collapse: true; light: false; title: ; toolbar: true; notranslate\" title=\"\">\r\n--&#x5B;&#x5B;\r\n* Kobold2D\u2122 --- http:\/\/www.kobold2d.org\r\n*\r\n* Copyright (c) 2010-2011 Steffen Itterheim. \r\n* Released under MIT License in Germany (LICENSE-Kobold2D.txt).\r\n--]]\r\n\r\n\r\n--&#x5B;&#x5B;\r\n* Need help with the KKStartupConfig settings?\r\n* ------ http:\/\/www.kobold2d.com\/x\/ygMO ------\r\n--]]\r\n\r\n\r\nlocal config =\r\n{\r\n    KKStartupConfig = \r\n    {\r\n        -- load first scene from a class with this name, or from a Lua script with this name with .lua appended\r\n        FirstSceneClassName = &quot;GameLayer&quot;,\r\n\r\n        -- set the director type, and the fallback in case the first isn't available\r\n        DirectorType = DirectorType.DisplayLink,\r\n        DirectorTypeFallback = DirectorType.NSTimer,\r\n\r\n        MaxFrameRate = 60,\r\n        DisplayFPS = YES,\r\n\r\n        EnableUserInteraction = YES,\r\n        EnableMultiTouch = NO,\r\n\r\n        -- Render settings\r\n        DefaultTexturePixelFormat = TexturePixelFormat.RGBA8888,\r\n        GLViewColorFormat = GLViewColorFormat.RGB565,\r\n        GLViewDepthFormat = GLViewDepthFormat.DepthNone,\r\n        GLViewMultiSampling = NO,\r\n        GLViewNumberOfSamples = 0,\r\n\r\n        Enable2DProjection = NO,\r\n        EnableRetinaDisplaySupport = YES,\r\n        EnableGLViewNodeHitTesting = NO,\r\n        EnableStatusBar = NO,\r\n\r\n        -- Orientation &amp; Autorotation\r\n        DeviceOrientation = DeviceOrientation.LandscapeLeft,\r\n        AutorotationType = Autorotation.None,\r\n        ShouldAutorotateToLandscapeOrientations = NO,\r\n        ShouldAutorotateToPortraitOrientations = NO,\r\n        AllowAutorotateOnFirstAndSecondGenerationDevices = NO,\r\n\r\n        -- Ad setup\r\n        EnableAdBanner = NO,\r\n        PlaceBannerOnBottom = YES,\r\n        LoadOnlyPortraitBanners = NO,\r\n        LoadOnlyLandscapeBanners = NO,\r\n        AdProviders = &quot;iAd, AdMob&quot;,\t-- comma seperated list -&gt; &quot;iAd, AdMob&quot; means: use iAd if available, otherwise AdMob\r\n        AdMobRefreshRate = 15,\r\n        AdMobFirstAdDelay = 5,\r\n        AdMobPublisherID = &quot;YOUR_ADMOB_PUBLISHER_ID&quot;, -- how to get an AdMob Publisher ID: http:\/\/developer.admob.com\/wiki\/PublisherSetup\r\n        AdMobTestMode = YES,\r\n\r\n        -- Mac OS specific settings\r\n        AutoScale = NO,\r\n        AcceptsMouseMovedEvents = NO,\r\n        WindowFrame = RectMake(1024-640, 768-480, 640, 480),\r\n        EnableFullScreen = NO,\r\n    },\r\n}\r\n\r\nreturn config\r\n<\/pre>\n<p><strong>Step 3 &#8211; GameLayer.h <\/strong><\/p>\n<p>Added are two variables to track the play. Line 16 is keeping track of the total times a moving target was started to descend down the screen.<\/p>\n<p>Line 17 tracks the number of times the moving target and the player collided.<\/p>\n<pre class=\"brush: objc; highlight: [16,17]; title: ; notranslate\" title=\"\">\r\n\/*\r\n * Kobold2D\u2122 --- http:\/\/www.kobold2d.org\r\n *\r\n * Copyright (c) 2010-2011 Steffen Itterheim. \r\n * Released under MIT License in Germany (LICENSE-Kobold2D.txt).\r\n *\/\r\n\r\n#import &quot;kobold2d.h&quot;\r\n\r\n@interface GameLayer : CCLayer\r\n{\r\n    CCSprite* player;\r\n    CGPoint playerVelocity;\r\n    CCSprite* movingTarget;\r\n\tfloat movingTargetMoveDuration;\r\n    int totalAttempts;\r\n    int totalHits;\r\n}\r\n@end\r\n<\/pre>\n<p><strong>Step 4 &#8211; Add checkForCollision Private Method<\/strong><\/p>\n<p>Complete GameLayer.m file is included here for your copy convenience. I will focus on the code changes to accommodate the collision detection.<\/p>\n<pre class=\"brush: objc; collapse: true; light: false; title: ; toolbar: true; notranslate\" title=\"\">\r\n\/*\r\n * Kobold2D\u2122 --- http:\/\/www.kobold2d.org\r\n *\r\n * Copyright (c) 2010-2011 Steffen Itterheim. \r\n * Released under MIT License in Germany (LICENSE-Kobold2D.txt).\r\n *\/\r\n\r\n#import &quot;GameLayer.h&quot;\r\n\r\n@interface GameLayer (PrivateMethods)\r\n-(void) initMovingTarget;\r\n-(void) movingTargetUpdate:(ccTime)delta;\r\n-(void) startMovingTargetSequence;\r\n-(void) endMovingTargetSequence;\r\n-(void) checkForCollision;\r\n@end\r\n\r\n\/\/ Velocity deceleration\r\nconst float deceleration = 0.4f;\r\n\/\/ Accelerometer sensitivity (higher = more sensitive)\r\nconst float sensitivity = 6.0f;\r\n\/\/ Maximum velocity\r\nconst float maxVelocity = 100.0f;\r\n\r\n@implementation GameLayer\r\n\r\n-(id) init\r\n{\r\n\tif ((self = &#x5B;super init]))\r\n\t{\r\n        \/\/ Enable accelerometer input events.\r\n\t\t&#x5B;KKInput sharedInput].accelerometerActive = YES;\r\n\t\t&#x5B;KKInput sharedInput].acceleration.filteringFactor = 0.2f;\r\n        \/\/ Initialize the total attempts to hit a moving target.\r\n        totalAttempts = 0;\r\n        \/\/ Initialize the total hits\r\n        totalHits = 0;\r\n        \/\/ Graphic for player\r\n        player = &#x5B;CCSprite spriteWithFile:@&quot;green_ball.png&quot;];\r\n\t\t&#x5B;self addChild:player z:0 tag:1];\r\n        \/\/ Position player        \r\n        CGSize screenSize = &#x5B;&#x5B;CCDirector sharedDirector] winSize];\r\n\t\tfloat imageHeight = &#x5B;player texture].contentSize.height;\r\n\t\tplayer.position = CGPointMake(screenSize.width \/ 2, imageHeight \/ 2);\r\n\t\tglClearColor(0.1f, 0.1f, 0.3f, 1.0f);\r\n\t\t\/\/ First line of title\r\n\t\tCCLabelTTF* label = &#x5B;CCLabelTTF labelWithString:@&quot;Kobold2d Intro Tutorial&quot; \r\n                                               fontName:@&quot;Arial&quot;  \r\n                                               fontSize:30];\r\n\t\tlabel.position = &#x5B;CCDirector sharedDirector].screenCenter;\r\n\t\tlabel.color = ccCYAN;\r\n        &#x5B;self addChild:label];\r\n        \/\/ Second line of title\r\n \t\tCCLabelTTF* label2 = &#x5B;CCLabelTTF labelWithString:@&quot;Lesson 5&quot;\r\n                                                fontName:@&quot;Arial&quot;\r\n                                                fontSize:24];\r\n\t\tlabel2.color = ccCYAN;\r\n        label2.position = CGPointMake(&#x5B;CCDirector sharedDirector].screenCenter.x ,label.position.y - label.boundingBox.size.height);\r\n        &#x5B;self addChild:label2];\r\n        \/\/ Seed random number generator\r\n        srandom((UInt32)time(NULL));\r\n        \/\/ Initialize our moving target.\r\n        &#x5B;self initMovingTarget];\r\n        \/\/ Start animation -  the update method is called.\r\n        &#x5B;self scheduleUpdate];;\r\n\t}\r\n\treturn self;\r\n}\r\n-(void) dealloc\r\n{\r\n#ifndef KK_ARC_ENABLED\r\n\t&#x5B;super dealloc];\r\n#endif \/\/ KK_ARC_ENABLED\r\n}\r\n#pragma mark Player Movement\r\n-(void) acceleratePlayerWithX:(double)xAcceleration\r\n{\r\n    \/\/ Adjust velocity based on current accelerometer acceleration\r\n    playerVelocity.x = (playerVelocity.x * deceleration) + (xAcceleration * sensitivity);\r\n    \/\/ Limit the maximum velocity of the player sprite, in both directions (positive &amp; negative values)\r\n    if (playerVelocity.x &gt; maxVelocity)\r\n    {\r\n        playerVelocity.x = maxVelocity;\r\n    }\r\n    else if (playerVelocity.x &lt; -maxVelocity)\r\n    {\r\n        playerVelocity.x = -maxVelocity;\r\n    }\r\n}\r\n#pragma mark update\r\n-(void) update:(ccTime)delta\r\n{\r\n    \/\/ Gain access to the user input devices \/ states\r\n    KKInput* input = &#x5B;KKInput sharedInput];\r\n    &#x5B;self acceleratePlayerWithX:input.acceleration.smoothedX];\r\n    \/\/ Accumulate up the playerVelocity to the player's position\r\n    CGPoint pos = player.position;\r\n    pos.x += playerVelocity.x;\r\n    \/\/ The player constrainted to inside the screen\r\n    CGSize screenSize = &#x5B;&#x5B;CCDirector sharedDirector] winSize];\r\n    \/\/ Half the player image size player sprite position is the center of the image\r\n    float imageWidthHalved = &#x5B;player texture].contentSize.width * 0.5f;\r\n    float leftBorderLimit = imageWidthHalved;\r\n    float rightBorderLimit = screenSize.width - imageWidthHalved;\r\n    \/\/ Hit left boundary\r\n    if (pos.x &lt; leftBorderLimit)\r\n    {\r\n        pos.x = leftBorderLimit;\r\n        \/\/ Set velocity to zero\r\n        playerVelocity = CGPointZero;\r\n    }\r\n    \/\/ Hit right boundary\r\n    else if (pos.x &gt; rightBorderLimit)\r\n    {\r\n        pos.x = rightBorderLimit;\r\n        \/\/ Set velocity to zero\r\n        playerVelocity = CGPointZero;\r\n    }\r\n    \/\/ Move the player\r\n    player.position = pos; \r\n    \/\/ Collision check\r\n    &#x5B;self checkForCollision];\r\n}  \r\n#pragma mark MovingTarget\r\n\r\n-(void) initMovingTarget\r\n{\r\n    NSLog(@&quot;initMovingTarget&quot;);\r\n    \/\/ This is the image\r\n\tmovingTarget = &#x5B;CCSprite spriteWithFile:@&quot;red_ball.png&quot;];\r\n    \/\/ Add CCSprite for movingTarget\r\n    &#x5B;self addChild:movingTarget z:0 tag:2];\r\n    \/\/ Set the starting position and start movingTarget play sequence\r\n    &#x5B;self startMovingTargetSequence];\r\n    movingTargetMoveDuration = 4.0f;\r\n   \t\/\/ Unschedule the selector just in case. If it isn't scheduled it won't do anything.\r\n\t&#x5B;self unschedule:@selector(movingTargetUpdate:)];\r\n\t\/\/ Schedule the movingTarget update logic to run at the given interval.\r\n\t&#x5B;self schedule:@selector(movingTargetUpdate:) interval:0.1f];\r\n}\r\n\r\n-(void) startMovingTargetSequence\r\n{\r\n    NSLog(@&quot;startMovingTargetSequence&quot;);\r\n    \/\/ Increment total attempts to hit a moving target.\r\n    totalAttempts ++;\r\n    \/\/ Get the window size\r\n    CGSize screenSize = &#x5B;&#x5B;CCDirector sharedDirector] winSize];\r\n    \/\/ Get the image size\r\n    CGSize imageSize = &#x5B;movingTarget texture].contentSize;\r\n    \/\/ Generate a random x starting position with offsets for center registration point.\r\n    int randomX = CCRANDOM_0_1() * (screenSize.width \/ imageSize.width);\r\n    movingTarget.position = CGPointMake(imageSize.width * randomX  + imageSize.width * 0.5f, screenSize.height + imageSize.height);\r\n    \/\/ Schedule the movingTarget update logic to run at the given interval.\r\n    &#x5B;self schedule:@selector(movingTargetUpdate:) interval:0.1f];\r\n}\r\n\r\n-(void) movingTargetUpdate:(ccTime)delta\r\n{\r\n    \/\/ CCSprite-&gt;CCNode no sequence of actions running.\r\n    if (&#x5B;movingTarget numberOfRunningActions] == 0)\r\n    {\r\n        NSLog(@&quot;movingTargetUpdate&quot;);\r\n        \/\/ Determine below screen position.\r\n        CGPoint belowScreenPosition = CGPointMake(movingTarget.position.x, - ( &#x5B;movingTarget texture].contentSize.height));\r\n        \/\/ CCAction to move a CCNode object to the position x,y based on position. \r\n        CCMoveTo* moveEnd = &#x5B;CCMoveTo actionWithDuration:movingTargetMoveDuration position:belowScreenPosition];\r\n        \/\/ Call back function for the action.\r\n        CCCallFuncN* callEndMovingTargetSequence = &#x5B;CCCallFuncN actionWithTarget:self selector:@selector(endMovingTargetSequence)];\r\n        \/\/ Create a sequence, add the actions: the moveEnd CCMoveTo and the call back function for the end position.\r\n        CCSequence* sequence = &#x5B;CCSequence actions:moveEnd,callEndMovingTargetSequence, nil];\r\n        \/\/ Run the sequence.\r\n        &#x5B;movingTarget runAction:sequence];\r\n    }\r\n}\r\n-(void) endMovingTargetSequence\r\n{\r\n    NSLog(@&quot;endMovingTargetSequence&quot;);\r\n    &#x5B;movingTarget stopAllActions];\r\n    \/\/ Terminate running the moveTargetUpdate interval.\r\n    &#x5B;self unschedule:@selector(movingTargetUpdate:)];\r\n    \/\/ Decrease the moving target move duration to increase the speed.\r\n    movingTargetMoveDuration -= 0.1f;\r\n    \/\/ Moving target move duration is below 2 then hold at 2.\r\n    if (movingTargetMoveDuration &lt; 2.0f)\r\n    {\r\n        movingTargetMoveDuration = 2.0f;\r\n    }\r\n    NSLog(@&quot;movingTargetMoveDuration: %f&quot;,movingTargetMoveDuration);\r\n    \/\/ Set the starting position and start movingTarget play sequence\r\n    &#x5B;self startMovingTargetSequence];\r\n}\r\n#pragma mark Collision Check\r\n-(void) checkForCollision\r\n{\r\n\t\/\/ Size of the player and target. Both are assumed squares so width suffices.\r\n\tfloat playerImageSize = &#x5B;player texture].contentSize.width;\r\n\tfloat targetImageSize = &#x5B;movingTarget texture].contentSize.width;\r\n\t\/\/ Compute their radii. Tweak based on drawing.\r\n\tfloat playerCollisionRadius = playerImageSize *.4;\r\n\tfloat targetCollisionRadius = targetImageSize *.4;\r\n\t\/\/ This collision distance will roughly equal the image shapes.\r\n\tfloat maxCollisionDistance = playerCollisionRadius + targetCollisionRadius;\r\n    \/\/ Distance between two points.\r\n    float actualDistance = ccpDistance(player.position, movingTarget.position);\r\n    \r\n    \/\/ Are the two objects closer than allowed?\r\n    if (actualDistance &lt; maxCollisionDistance)\r\n    {\r\n        totalHits++;\r\n        NSLog(@&quot;HIT! Total attempts: %i. Total hits: %i&quot;, totalAttempts, totalHits);\r\n        &#x5B;self endMovingTargetSequence];\r\n    }\r\n}\r\n@end\r\n<\/pre>\n<p>First set of changes are in the declaration of a new private method checkForCollision.<\/p>\n<pre class=\"brush: objc; first-line: 8; highlight: [15]; title: ; notranslate\" title=\"\">\r\n#import &quot;GameLayer.h&quot;\r\n\r\n@interface GameLayer (PrivateMethods)\r\n-(void) initMovingTarget;\r\n-(void) movingTargetUpdate:(ccTime)delta;\r\n-(void) startMovingTargetSequence;\r\n-(void) endMovingTargetSequence;\r\n-(void) checkForCollision;\r\n@end\r\n<\/pre>\n<p>[ad name=&#8221;Google Adsense&#8221;]<br \/>\n<strong>Step 5 &#8211; Initialize Scoring Properties and Update Subtitle<\/strong><\/p>\n<p>The scoring properties are initialized on lines 35 and 37.<\/p>\n<p>Line 54 clarifies the lesson in the subtitle.<\/p>\n<pre class=\"brush: objc; first-line: 27; highlight: [35,37,54]; title: ; notranslate\" title=\"\">\r\n-(id) init\r\n{\r\n\tif ((self = &#x5B;super init]))\r\n\t{\r\n        \/\/ Enable accelerometer input events.\r\n\t\t&#x5B;KKInput sharedInput].accelerometerActive = YES;\r\n\t\t&#x5B;KKInput sharedInput].acceleration.filteringFactor = 0.2f;\r\n        \/\/ Initialize the total attempts to hit a moving target.\r\n        totalAttempts = 0;\r\n        \/\/ Initialize the total hits\r\n        totalHits = 0;\r\n        \/\/ Graphic for player\r\n        player = &#x5B;CCSprite spriteWithFile:@&quot;green_ball.png&quot;];\r\n\t\t&#x5B;self addChild:player z:0 tag:1];\r\n        \/\/ Position player        \r\n        CGSize screenSize = &#x5B;&#x5B;CCDirector sharedDirector] winSize];\r\n\t\tfloat imageHeight = &#x5B;player texture].contentSize.height;\r\n\t\tplayer.position = CGPointMake(screenSize.width \/ 2, imageHeight \/ 2);\r\n\t\tglClearColor(0.1f, 0.1f, 0.3f, 1.0f);\r\n\t\t\/\/ First line of title\r\n\t\tCCLabelTTF* label = &#x5B;CCLabelTTF labelWithString:@&quot;Kobold2d Intro Tutorial&quot; \r\n                                               fontName:@&quot;Arial&quot;  \r\n                                               fontSize:30];\r\n\t\tlabel.position = &#x5B;CCDirector sharedDirector].screenCenter;\r\n\t\tlabel.color = ccCYAN;\r\n        &#x5B;self addChild:label];\r\n        \/\/ Second line of title\r\n \t\tCCLabelTTF* label2 = &#x5B;CCLabelTTF labelWithString:@&quot;Lesson 5&quot;\r\n                                                fontName:@&quot;Arial&quot;\r\n                                                fontSize:24];\r\n\t\tlabel2.color = ccCYAN;\r\n        label2.position = CGPointMake(&#x5B;CCDirector sharedDirector].screenCenter.x ,label.position.y - label.boundingBox.size.height);\r\n        &#x5B;self addChild:label2];\r\n        \/\/ Seed random number generator\r\n        srandom((UInt32)time(NULL));\r\n        \/\/ Initialize our moving target.\r\n        &#x5B;self initMovingTarget];\r\n        \/\/ Start animation -  the update method is called.\r\n        &#x5B;self scheduleUpdate];;\r\n\t}\r\n\treturn self;\r\n}\r\n<\/pre>\n<p><strong>Step 6 &#8211; Call the Collision Detection Method<\/strong><\/p>\n<p>Each time the game data is updated you also can check for any collisions. The update method is called for each iteration in the game. <\/p>\n<p>You can just put the message for the checkForCollision, shown on line 122, at the end. By the end of checkForCollision the player and moving targets are in their new positions and a perfect place to check for an overlap.<\/p>\n<pre class=\"brush: objc; first-line: 90; highlight: [122]; title: ; notranslate\" title=\"\">\r\n#pragma mark update\r\n-(void) update:(ccTime)delta\r\n{\r\n    \/\/ Gain access to the user input devices \/ states\r\n    KKInput* input = &#x5B;KKInput sharedInput];\r\n    &#x5B;self acceleratePlayerWithX:input.acceleration.smoothedX];\r\n    \/\/ Accumulate up the playerVelocity to the player's position\r\n    CGPoint pos = player.position;\r\n    pos.x += playerVelocity.x;\r\n    \/\/ The player constrainted to inside the screen\r\n    CGSize screenSize = &#x5B;&#x5B;CCDirector sharedDirector] winSize];\r\n    \/\/ Half the player image size player sprite position is the center of the image\r\n    float imageWidthHalved = &#x5B;player texture].contentSize.width * 0.5f;\r\n    float leftBorderLimit = imageWidthHalved;\r\n    float rightBorderLimit = screenSize.width - imageWidthHalved;\r\n    \/\/ Hit left boundary\r\n    if (pos.x &lt; leftBorderLimit)\r\n    {\r\n        pos.x = leftBorderLimit;\r\n        \/\/ Set velocity to zero\r\n        playerVelocity = CGPointZero;\r\n    }\r\n    \/\/ Hit right boundary\r\n    else if (pos.x &gt; rightBorderLimit)\r\n    {\r\n        pos.x = rightBorderLimit;\r\n        \/\/ Set velocity to zero\r\n        playerVelocity = CGPointZero;\r\n    }\r\n    \/\/ Move the player\r\n    player.position = pos; \r\n    \/\/ Collision check\r\n    &#x5B;self checkForCollision];\r\n}  \r\n<\/pre>\n<p><strong>Step 7 &#8211; Kill The Moving Target Actions<\/strong><\/p>\n<p>The endMovingTargetSequence method can be called once a collision is detected. It is set up to clean up the current moving target and call the startMovingTargetSequence for the next moving target.<\/p>\n<p>However endMovingTargetSequence presents a timing issue between the update of the game and the number of times the moving target actions occur. For each game update you will observe multiple calls for the moving target CCMoveTo moveEnd  action defined in movingTargetUpdate. <\/p>\n<p>That creates an opening for multiple hits before line 181 unschedule gets fired. So the moving target will proceed through the position of the player and each update will detect a collision.<\/p>\n<p>The solution is to add  the <a href=\"http:\/\/www.cocos2d-iphone.org\/api-ref\/2.0.0\/interface_c_c_node.html#a24f2916259df943e3f13cdd702673962\" target = \"_blank\">stopAllActions<\/a> method is from Cocos2D CCNode class. Making stopAllActions the first line results in immediate termination of all actions for the moving target. See line 179.<\/p>\n<pre class=\"brush: objc; first-line: 176; highlight: [179]; title: ; notranslate\" title=\"\">\r\n-(void) endMovingTargetSequence\r\n{\r\n    NSLog(@&quot;endMovingTargetSequence&quot;);\r\n    &#x5B;movingTarget stopAllActions];\r\n    \/\/ Terminate running the moveTargetUpdate interval.\r\n    &#x5B;self unschedule:@selector(movingTargetUpdate:)];\r\n    \/\/ Decrease the moving target move duration to increase the speed.\r\n    movingTargetMoveDuration -= 0.1f;\r\n    \/\/ Moving target move duration is below 2 then hold at 2.\r\n    if (movingTargetMoveDuration &lt; 2.0f)\r\n    {\r\n        movingTargetMoveDuration = 2.0f;\r\n    }\r\n    NSLog(@&quot;movingTargetMoveDuration: %f&quot;,movingTargetMoveDuration);\r\n    \/\/ Set the starting position and start movingTarget play sequence\r\n    &#x5B;self startMovingTargetSequence];\r\n}\r\n<\/pre>\n<p><strong>Step 8 &#8211; Count the Total Moving Targets<\/strong><\/p>\n<p>The startMovingTargetSequence is fired each time a new moving target is added. This is where, see line 146, to increment the counter for the number of moving targets.<\/p>\n<pre class=\"brush: objc; first-line: 142; highlight: [146]; title: ; notranslate\" title=\"\">\r\n-(void) startMovingTargetSequence\r\n{\r\n    NSLog(@&quot;startMovingTargetSequence&quot;);\r\n    \/\/ Increment total attempts to hit a moving target.\r\n    totalAttempts ++;\r\n    \/\/ Get the window size\r\n    CGSize screenSize = &#x5B;&#x5B;CCDirector sharedDirector] winSize];\r\n    \/\/ Get the image size\r\n    CGSize imageSize = &#x5B;movingTarget texture].contentSize;\r\n    \/\/ Generate a random x starting position with offsets for center registration point.\r\n    int randomX = CCRANDOM_0_1() * (screenSize.width \/ imageSize.width);\r\n    movingTarget.position = CGPointMake(imageSize.width * randomX  + imageSize.width * 0.5f, screenSize.height + imageSize.height);\r\n    \/\/ Schedule the movingTarget update logic to run at the given interval.\r\n    &#x5B;self schedule:@selector(movingTargetUpdate:) interval:0.1f];\r\n}\r\n<\/pre>\n<p>[ad name=&#8221;Google Adsense&#8221;]<br \/>\n<strong>Step 9 &#8211; Add Collision Detection Method<\/strong><\/p>\n<p>The checkForCollision method is our new method that handles collisions between the moving target and the player.<\/p>\n<p>The process is twofold. One to compute the distance that defines a collision. Lines 196 &#8211; 203 do that. The measurement is based on the graphics and their center registration point and any offset you want to add to that based on observing the collisions. <\/p>\n<p> Second part of the collision detection process is computing the actual dist and and line 205 does that for us.<\/p>\n<p>Line 208 defines a code block if there is hit and in that code block the totalHits counter is incremented and the endMovingTargetSequence method is called to remove the moving target.<\/p>\n<pre class=\"brush: objc; first-line: 193; title: ; notranslate\" title=\"\">\r\n#pragma mark Collision Check\r\n-(void) checkForCollision\r\n{\r\n\t\/\/ Size of the player and target. Both are assumed squares so width suffices.\r\n\tfloat playerImageSize = &#x5B;player texture].contentSize.width;\r\n\tfloat targetImageSize = &#x5B;movingTarget texture].contentSize.width;\r\n\t\/\/ Compute their radii. Tweak based on drawing and observations.\r\n\tfloat playerCollisionRadius = playerImageSize *.4;\r\n\tfloat targetCollisionRadius = targetImageSize *.4;\r\n\t\/\/ This collision distance will roughly equal the image shapes.\r\n\tfloat maxCollisionDistance = playerCollisionRadius + targetCollisionRadius;\r\n    \/\/ Distance between two points.\r\n    float actualDistance = ccpDistance(player.position, movingTarget.position);\r\n    \r\n    \/\/ Are the two objects closer than allowed?\r\n    if (actualDistance &lt; maxCollisionDistance)\r\n    {\r\n        totalHits++;\r\n        NSLog(@&quot;HIT! Total attempts: %i. Total hits: %i&quot;, totalAttempts, totalHits);\r\n        &#x5B;self endMovingTargetSequence];\r\n    }\r\n}\r\n<\/pre>\n<p><!-- Place this tag where you want the +1 button to render --><br \/>\n<g:plusone annotation=\"inline\"><\/g:plusone><br \/>\n<a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/12\/21\/kobold2d-xcode-4-introduction-tutorial-lesson-4-progressively-increase-moving-target-speed\/\">&lt;== Lesson 4<\/a> || <a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/12\/23\/kobold2d-xcode-4-introduction-tutorial-lesson-6-add-collision-sound-effect\/\">Lesson 6 ==&gt; <\/a>  <\/p>\n<div id=\"fb-root\"><\/div>\n<p><script src=\"https:\/\/connect.facebook.net\/en_US\/all.js#appId=105467682877384&amp;xfbml=1\"><\/script><fb:like href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/12\/18\/kobold2d-xcode-4-introduction-tutorial-lesson-1-basic-accelerometer\/\" send=\"true\" width=\"450\" show_faces=\"true\" font=\"\"><\/fb:like><\/p>\n<div id=\"fb-root\"><\/div>\n<p><script src=\"https:\/\/connect.facebook.net\/en_US\/all.js#xfbml=1\"><\/script><fb:comments href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/12\/18\/kobold2d-xcode-4-introduction-tutorial-lesson-1-basic-accelerometer\/\" num_posts=\"3\" width=\"500\"><\/fb:comments><\/p>\n<p>[ad name=&#8221;Google Adsense&#8221;]<br \/>\n<!-- Place this render call where appropriate --><br \/>\n<script type=\"text\/javascript\">\n  (function() {\n    var po = document.createElement('script'); po.type = 'text\/javascript'; po.async = true;\n    po.src = 'https:\/\/apis.google.com\/js\/plusone.js';\n    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);\n  })();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&lt;== Lesson 4 || Lesson 6 ==&gt; Now its time to detect the collision of the moving target and the player. For this game, the collision is a good thing as that is the goal. So we will call collisions between the player and the moving target a hit. To plan ahead, you will also [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[78,79,31,77],"class_list":["post-2759","post","type-post","status-publish","format-standard","hentry","category-general","tag-accelerometer","tag-cocos2d","tag-gaming","tag-kobold2d"],"_links":{"self":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/2759","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/comments?post=2759"}],"version-history":[{"count":25,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/2759\/revisions"}],"predecessor-version":[{"id":3662,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/2759\/revisions\/3662"}],"wp:attachment":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/media?parent=2759"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/categories?post=2759"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/tags?post=2759"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}