iOS Game Development
    with Cocos2D




       SaalisUmer
  saalis.umer@vinsol.com
iOS Game Development
        with Cocos2D


Part 1: Why Cocos2D?
Part 2: Cocos2D Basics
Part 3: Let’s build a Cocos2D game
Part 1:
Why Cocos2D?
Anatomy of a simple game
      CPU & GPU
Meet Cocos2D for iPhone
 Open source iOS game development framework
 Developed by Ricardo Quesada, acqui-hired by
Zynga (2011)
 Stable v1.1 Based on OpenGL ES 1.1
 Beta v2.0 Based on OpenGL ES 2.0
 3,500+ iOS games shipped
The Cocos2D Family


                                                                   Cocos3D
                                                                   (Obj-C)

Cocos2d-Android
     (Java)
                                                    Cocos2d-Mac
                              Cocos2d-X               (Obj-C)
                         iPhone/Android (C++)




     Cocos2d-XNA                                Cocos2d-HTML5
  Windows Phone 7 (C#)                          Web (Javascript)
Proven Success
Great Effort-Flexibility Balance

                           Direct OpenGL/
100                         CoreGraphics




                                    Cocos2D/Sparrow

       Unity/Corona
  0
                      Flexibility
Cross Device, Cross Resolution
Active Ecosystem
And most importantly..
  Tons of great features for games

  Sprite Sheets             Scene Transitions          Parallax Scrolling



     Effects:                                            Actions:
                           Tile Map Support
Lense, Ripple, Wave..                                Move, Rotate, Scale..



Particle Systems        Integrated Physics Engines       Text Rendering



   Ribbons                   Shaders (v2.0)              Sound Support
Part 2:
Cocos2D Basics
Basic Cocos2D Concepts
                  Class that creates and handle the main Window
       Director   and manages how and when to execute the Scenes.
Basic Cocos2D Concepts
                  Creates and handle the main Window
       Director   and manages how and when to execute the Scenes.




                   A scene (implemented with the CCScene object) is more
        Scenes     or less an independent piece of the app workflow. .
Basic Cocos2D Concepts
                                                        Creates and handle the main Window
                                             Director   and manages how and when to execute the Scenes.




                                                         A scene (implemented with the CCScene object) is more
                                             Scenes      or less an independent piece of the app workflow. .




A CCLayer has a size of the whole drawable    Layers
area, and knows how to draw itself.
Basic Cocos2D Concepts
                                                      Creates and handle the main Window
                                           Director   and manages how and when to execute the Scenes.




                                                       A scene (implemented with the CCScene object) is more
                                           Scenes      or less an independent piece of the app workflow. .




A layer has a size of the whole drawable
                                            Layers
area, and knows how to draw itself.


It is a 2D image that can be moved,        Sprites
rotated, scaled, animated, etc.
Director & Scenes
Director                  Loss


Intro      Main Menu     Level I     Level 2   Victory


                        Options


                       High Scores



   Game made up of “game screens” called Scenes
   Each Scene can be considered a separate app
   Director handles main window and executes Scenes
Layers




Each Scene contains several full screen Layers
Layers contain Sprites which are the game elements
Layers useful for Controls, Background, Labels, Menus.
Nodes


Nodes are anything that gets drawn or contains
things that get drawn (= Scene, Layer, Sprite)
Can: Contain other Nodes
        Schedule periodic callbacks
        Execute Actions
Sprites in Action

                                                Create




CCSpriteFrame* spriteFrame = [[CCSpriteFrameCachesharedSpriteFrameCache]
spriteFrameByName:@"sprite.png”];
CCSprite* sprite = [CCSpritespriteWithSpriteFrame:spriteFrame];
Sprites in Action
winSize.height


                                           Add to Layer


                                  (x,y) at anchor point




                                                          winSize.width
 (0,0)
                 sprite.position = ccp(x, y);

                 [layer addChild:sprite z:5 tag:666];
Sprites in Action

                                                 Move




  CCMoveTo *moveToAction = [CCMoveToactionWithDuration:duration
                                               position:newPosition];

  [sprite runAction:moveToAction];


Properties can be transformed directly or through actions
Sprites in Action

                                                 Scale/Rotate




CCScaleTo *scaleToAction = [CCScaleToactionWithDuration:durationscale:scale];
CCRotateBy *rotateByAction = [CCRotateByactionWithDuration:durationangle:angle];

CCSequence *sequence = [CCSequenceactions:scaleToAction, rotateByAction, nil];

[sprite runAction:sequence];
Sprites in Action

                                           Animate




CCAnimation* animation = [[CCAnimationCachesharedAnimationCache]
                                       animationByName:@"animation"];
CCAnimate* animateAction = [CCAnimateactionWithAnimation:animation];

[sprite runAction:animateAction];
Sprites in Action

                                Schedule Updates




[scene schedule:@selector(updateSprite:) interval:interval];
Actions
     Can be performed on Sprites or any Node


   Basic      Move, Scale, Rotate, Bezier, Hide, Fade, Tint..

Composition   Sequence, Repeat, Spawn, RepeatForever..

   Ease          Ease, EaseExponential, EaseBounce..

  Effects       Lens, Liquid, Ripple, Shaky, Twirl, Waves..

  Special                 CallFunc, Follow..
Spritesheets




Added as a child to the layer
Created with TexturePacker or Zwoptex
Memory considerations, 16bit images, .pvr.ccz
Controls

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;




Implement directly based on CCStandardTouchDelegate
Can use UIGestureRecognizer classes
Open source implementations of joypad/buttons available
Part 3:
Let’s Make a Game!
Part 3:
Let’s Make a Game!
..but first we need a story, graphics, music and sfx :)
KillTime




Because he likes to kill paratroopers
Graphics




http://www.freewebs.com/teh_pro/sprites.htm
Music & SFX




Background music, shoot sound, death sound
Steps for making KillTime
Application Setup
Step 1: Adding Background
Step 2: Adding Our Hero
Step 3: Adding Bad Guys (Game Logic)
Step 4: Killing Bad Guys (Adding UI)
Step 5: Check for Bad Guy Death
Step 6: Animating Our Hero
Step 7: Animating Bad Guys Dying
Step 8: Adding Body Count
Step 9: Adding Sound & Music
New Cocos2D Project
HelloWorldScene.h
@interface HelloWorldLayer : CCLayer
{
   // Player sprite
CCSprite *_player;

   // Target and bullet sprite arrays
NSMutableArray *_targets;
NSMutableArray *_bullets;

!   // Body count counter and isShooting flag
    int _bodyCount;
    BOOL _isShooting;
!
   // For body count label
CCLabelTTF *_labelTitle;
CCLabelTTF *_labelCount;
}
HelloWorldScene.m

// Create the new scene including this layer
+(id) scene
{
! // Create the scene
CCScene *scene = [CCScene node];
!
! // Create the layer
HelloWorldLayer *layer = [HelloWorldLayer node];
!
! // add layer as a child to scene
! [scene addChild: layer];
!
! // return the scene
  return scene;
}
Hello World
Step 1: Adding Background


(In init)

// Get the window size to place elements
CGSizewinSize = [[CCDirectorsharedDirector] winSize];
// Add the background image
CCSprite *background = [CCSpritespriteWithFile:@"background.png"];
background.position = ccp(winSize.width/2, winSize.height/2);
[self addChild:background z:0];
self.isTouchEnabled = YES; _bullets = [[NSMutableArrayalloc]init];
_targets = [[NSMutableArrayalloc]init];
Step 1: Adding Background
Step 2: Adding Our Hero
                     Preload the spritesheet




(In init)
// Load the sprite sheet
CCSpriteBatchNode *batchNode = [CCSpriteBatchNode
                   batchNodeWithFile:@”spritesheet.pvr.ccz"];
[self addChild:batchNode];

// Load the sprites into the shareSpriteFrameCache
[[CCSpriteFrameCachesharedSpriteFrameCache]
               addSpriteFramesWithFile:@”spritesheet.plist"];
Step 2: Adding Our Hero
                         Add the hero sprite



// Add the player sprite
CCSpriteFrame* playerFrame = [[CCSpriteFrameCachesharedSpriteFrameCache]
spriteFrameByName:@"player1.png"];

_player = [CCSpritespriteWithSpriteFrame:playerFrame];
_player.position = ccp(_player.contentSize.width/2 + 10, winSize.height/2);

[self addChild:_player z:1];
Step 2: Adding Our Hero
Step 3: Adding Bad Guys (Game Logic)
            Schedule a new target every second




(in init)

[self schedule:@selector(addTarget:) interval:1.0f];
Step 3: Adding Bad Guys (Game Logic)
                      Create a sprite for the target




// Create a new enemy
-(void)addTarget:(ccTime)dt {

     // Create the target sprite
    CCSpriteFrame *targetFrame = [[CCSpriteFrameCachesharedSpriteFrameCache]
    spriteFrameByName:@"target.png”];
    CCSprite *target = [CCSpritespriteWithSpriteFrame:targetFrame];

    // Add the target to the layer and the array
!   [self addChild:target];
!   [_targets addObject:target];}
Step 3: Adding Bad Guys (Game Logic)
         Generate a random x position for the target


    // Determine where to spawn the target along the X axis
CGSizewinSize = [[CCDirectorsharedDirector] winSize];

    // Find a random X for the target in the right half of the screen
intminX = winSize.width/2;
intmaxX = winSize.width - target.contentSize.width;
intrangeX = maxX - minX;
intactualX = (arc4random() % rangeX) + minX;
    target.    position        =     ccp     (actualX,      320    );
    target.anchorPoint = ccp(0, 0);

    // Determine speed of the target
intminDuration = 2.0;
intmaxDuration = 4.0;
intrangeDuration = maxDuration - minDuration;
intactualDuration = (arc4random() % rangeDuration) + minDuration;
Step 3: Adding Bad Guys (Game Logic)
               Create a move action for the target with a
                  callback when reaching the bottom


// Create and run the actions
CCMoveTo* moveTarget = [CCMoveToactionWithDuration:actualDuration
              Position:ccp(actualX,-target.contentSize.height/2)];
CCCallFuncN* actionForTargetMoveDidFinish = [CCCallFuncN
             actionWithTarget:selfselector:@selector(targetMoveFinished:)];

[target runAction:[CCSequenceactions:moveTarget, actionForTargetMoveDidFinish, nil]];
Step 3: Adding Bad Guys (Game Logic)
         Add the callback method for a target that
               dies or reaches the bottom

// Method for removing a target that has died or reached the
bottom

-(void)targetMoveFinished:(id)sender {
CCSprite *target = (CCSprite *)sender;
   [ self       removeChild      :target   cleanup    :    YES   ];
[_targets removeObject:target];
}
Step 3: Adding Bad Guys (Game Logic)
Step 4: Killing Bad Guys (Adding UI)
                              Detect the touch




- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
   location = [[CCDirectorsharedDirector] convertToGL:location];

    if (!_isShooting) {
        _isShooting = YES;
Step 4: Killing Bad Guys (Adding UI)
                               Create the bullet

// Create the bullet
CCSpriteFrame* bulletFrame = [[CCSpriteFrameCachesharedSpriteFrameCache]
spriteFrameByName:                        @"bullet.png"     ];
CCSprite* bulletSprite = [CCSpritespriteWithSpriteFrame:bulletFrame];
bulletSprite.position = _player.position;

 // Bullet actions
 CCCallFuncN* actionForRemoveBullet = [CCCallFuncNactionWithTarget:self
                                        selector:@selector(removeBullet:)];
 CCMoveBy* bulletMoveBy = [CCMoveBy actionWithDuration:1.0f
                                              position:ccp(winSize.width, 0)];
 [bulletSpriterunAction:[CCSequenceactionOne:bulletMoveBy
                                           two:actionForRemoveBullet]];
// Add bullet to layer and array
[self addChild:bulletSprite];
[_bullets addObject:bulletSprite];
_isShooting = NO;
Step 4: Killing Bad Guys (Adding UI)
Step 5: Check for Bad Guy Death

-(void)update:(ccTime)dt {
    CCSprite* bulletToRemove = nil;

    for (CCSprite *bullet in _bullets) {
        for (CCSprite* target in _targets) {
            CGRecttargetBox = CGRectMake(target.position.x, target.position.y,
                  [target boundingBox].size.width, [target boundingBox].size.height);

            // Check if bullet is in the target's bounding box
            if (CGRectContainsPoint(targetBox, bullet.position)) {

            // Animate target death and remove target

                bulletToRemove = bullet;
            }
        }
    }

    // Remove bullet if target was hit
    if (bulletToRemove != nil) {
        [self removeChild:bulletToRemovecleanup:YES];
        [ _bullets                removeObject   :bulletToRemove];
    }
}
Step 5: Check for Bad Guy Death
Step 6: Animating Our Hero
             Preload the animation from the spritesheet


 Adding Player animation in init
(In init)

// Load the animation for player
NSMutableArray *animFrames1 = [NSMutableArray array];
for (inti = 1; i< 11; i++) {
    CCSpriteFrame *frame = [[CCSpriteFrameCachesharedSpriteFrameCache] spriteFrameByName:
                                         [NSStringstringWithFormat:@"player%d.png”,i]];
    [animFrames1 addObject:frame];
}

[[CCAnimationCachesharedAnimationCache] addAnimation:[CCAnimation
                  animationWithFrames:animFrames1 delay:FRAME_DELAY] name:@"player"];!
Step 6: Animating Our Hero
             Preload the animation from the spritesheet


 Adding Kill animation in init
(In init)

//// Load the animation for villain kill
NSMutableArray *animFrames2 = [NSMutableArray array];
for (inti = 1; i< 8; i++) {
CCSpriteFrame *frame2 = [[CCSpriteFrameCachesharedSpriteFrameCache] spriteFrameByName:
[NSStringstringWithFormat:@"kill%d.png",i]];
[animFrames2 addObject:frame2];
 }
[[CCAnimationCachesharedAnimationCache] addAnimation:[CCAnimation
animationWithFrames:animFrames2 delay:FRAME_DELAY*5] name:@"kill"];
Step 6: Animating Our Hero
                      Animate the hero when shooting



(In ccTouchesEnded)

// Actions for shooting animation
CCCallFunc* actionForShootDidEnd = [CCCallFuncactionWithTarget:self
                                                selector:@selector(shootDidEnd)];

CCAnimation* playerShootAnimation = [[CCAnimationCachesharedAnimationCache]
                                                      animationByName:@"player"];
CCAnimate* shootAnimate = [CCAnimateactionWithAnimation:playerShootAnimation];

[_player runAction:[CCSequenceactionOne:shootAnimatetwo:actionForShootDidEnd]];
Step 6: Animating Our Hero
Step 7: Animating Bad Guys Dying



(in update)

// Set up actions for animation and target removal
CCCallFuncN* actionForDeathDidFinish = [CCCallFuncNactionWithTarget:self
                                                   selector:@selector(targetMoveFinished:)];

CCAnimate* deathAnimation = [CCAnimateactionWithAnimation:[[CCAnimationCache
                 sharedAnimationCache] animationByName:@”kill"] restoreOriginalFrame:NO];

[target runAction:[CCSequenceactionOne:deathAnimationtwo:actionForDeathDidFinish]];
Step 7: Animating Bad Guys Dying
Step 8: Adding Body Count


(In init)

NSString* bodyCountString = [NSStringstringWithFormat:@"%d", _bodyCount];
_labelCount = [CCLabelTTFlabelWithString:bodyCountStringfontName:@"Arial"
fontSize                                                  : 16     ];
_labelCount.color = ccc3(0,0,0);
_labelCount.position = ccp(110, winSize.height - 16);
[self addChild:_labelCount z:2];

(In update:)

_bodyCount++;
NSString* bodyCountString = [NSStringstringWithFormat:@"%d", _bodyCount];!
[_labelCountsetString:bodyCountString];
Step 8: Adding Body Count
Step 9: Adding Sound & Music


(In init)

!   // Start background music, set lower volume

SimpleAudioEngine.sharedEngine.backgroundMusicVolume = 0.4f;
! [[SimpleAudioEnginesharedEngine] playBackgroundMusic:@"explosive_attack.mp3"];

(In ccTouchesEnded)
   // Play sound effect on every shot and on death
!
   [[SimpleAudioEnginesharedEngine] playEffect:@"shot.mp3"];
!(In update: where the target is killed)
! [[SimpleAudioEnginesharedEngine] playEffect:@"death.mp3"];
Let’s Play!
KillTime 2.0

Enemies can move and attack
Joypad
Move our hero
Different weapons, power ups and health
Game menu and high scores
Levels
Save/Load Game
Refactor code (More scenes and layers)
More stuff to explore


Physics Engines - Chipmunk and Box2D
Particle System
Tilemaps
Menu Interface
Where can you learn more

       Cocos2D Demo Library (Comes with Cocos)

            Wiki: http://cocos2d-iphone.org/wiki

       Ray Wenderlich: http://www.raywenderlich.com

       Steffen Itterheim: http://learn-cocos2d.com

Sapus Tongue Source Code: http://www.sapusmedia.com/source
Thank You!
  SAALIS UMER

Game development with Cocos2d

  • 1.
    iOS Game Development with Cocos2D SaalisUmer saalis.umer@vinsol.com
  • 2.
    iOS Game Development with Cocos2D Part 1: Why Cocos2D? Part 2: Cocos2D Basics Part 3: Let’s build a Cocos2D game
  • 3.
  • 4.
    Anatomy of asimple game CPU & GPU
  • 5.
    Meet Cocos2D foriPhone Open source iOS game development framework Developed by Ricardo Quesada, acqui-hired by Zynga (2011) Stable v1.1 Based on OpenGL ES 1.1 Beta v2.0 Based on OpenGL ES 2.0 3,500+ iOS games shipped
  • 6.
    The Cocos2D Family Cocos3D (Obj-C) Cocos2d-Android (Java) Cocos2d-Mac Cocos2d-X (Obj-C) iPhone/Android (C++) Cocos2d-XNA Cocos2d-HTML5 Windows Phone 7 (C#) Web (Javascript)
  • 7.
  • 8.
    Great Effort-Flexibility Balance Direct OpenGL/ 100 CoreGraphics Cocos2D/Sparrow Unity/Corona 0 Flexibility
  • 9.
  • 10.
  • 11.
    And most importantly.. Tons of great features for games Sprite Sheets Scene Transitions Parallax Scrolling Effects: Actions: Tile Map Support Lense, Ripple, Wave.. Move, Rotate, Scale.. Particle Systems Integrated Physics Engines Text Rendering Ribbons Shaders (v2.0) Sound Support
  • 12.
  • 13.
    Basic Cocos2D Concepts Class that creates and handle the main Window Director and manages how and when to execute the Scenes.
  • 14.
    Basic Cocos2D Concepts Creates and handle the main Window Director and manages how and when to execute the Scenes. A scene (implemented with the CCScene object) is more Scenes or less an independent piece of the app workflow. .
  • 15.
    Basic Cocos2D Concepts Creates and handle the main Window Director and manages how and when to execute the Scenes. A scene (implemented with the CCScene object) is more Scenes or less an independent piece of the app workflow. . A CCLayer has a size of the whole drawable Layers area, and knows how to draw itself.
  • 16.
    Basic Cocos2D Concepts Creates and handle the main Window Director and manages how and when to execute the Scenes. A scene (implemented with the CCScene object) is more Scenes or less an independent piece of the app workflow. . A layer has a size of the whole drawable Layers area, and knows how to draw itself. It is a 2D image that can be moved, Sprites rotated, scaled, animated, etc.
  • 17.
    Director & Scenes Director Loss Intro Main Menu Level I Level 2 Victory Options High Scores Game made up of “game screens” called Scenes Each Scene can be considered a separate app Director handles main window and executes Scenes
  • 18.
    Layers Each Scene containsseveral full screen Layers Layers contain Sprites which are the game elements Layers useful for Controls, Background, Labels, Menus.
  • 19.
    Nodes Nodes are anythingthat gets drawn or contains things that get drawn (= Scene, Layer, Sprite) Can: Contain other Nodes Schedule periodic callbacks Execute Actions
  • 20.
    Sprites in Action Create CCSpriteFrame* spriteFrame = [[CCSpriteFrameCachesharedSpriteFrameCache] spriteFrameByName:@"sprite.png”]; CCSprite* sprite = [CCSpritespriteWithSpriteFrame:spriteFrame];
  • 21.
    Sprites in Action winSize.height Add to Layer (x,y) at anchor point winSize.width (0,0) sprite.position = ccp(x, y); [layer addChild:sprite z:5 tag:666];
  • 22.
    Sprites in Action Move CCMoveTo *moveToAction = [CCMoveToactionWithDuration:duration position:newPosition]; [sprite runAction:moveToAction]; Properties can be transformed directly or through actions
  • 23.
    Sprites in Action Scale/Rotate CCScaleTo *scaleToAction = [CCScaleToactionWithDuration:durationscale:scale]; CCRotateBy *rotateByAction = [CCRotateByactionWithDuration:durationangle:angle]; CCSequence *sequence = [CCSequenceactions:scaleToAction, rotateByAction, nil]; [sprite runAction:sequence];
  • 24.
    Sprites in Action Animate CCAnimation* animation = [[CCAnimationCachesharedAnimationCache] animationByName:@"animation"]; CCAnimate* animateAction = [CCAnimateactionWithAnimation:animation]; [sprite runAction:animateAction];
  • 25.
    Sprites in Action Schedule Updates [scene schedule:@selector(updateSprite:) interval:interval];
  • 26.
    Actions Can be performed on Sprites or any Node Basic Move, Scale, Rotate, Bezier, Hide, Fade, Tint.. Composition Sequence, Repeat, Spawn, RepeatForever.. Ease Ease, EaseExponential, EaseBounce.. Effects Lens, Liquid, Ripple, Shaky, Twirl, Waves.. Special CallFunc, Follow..
  • 27.
    Spritesheets Added as achild to the layer Created with TexturePacker or Zwoptex Memory considerations, 16bit images, .pvr.ccz
  • 28.
    Controls - (void)ccTouchesBegan:(NSSet *)toucheswithEvent:(UIEvent *)event; - (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; Implement directly based on CCStandardTouchDelegate Can use UIGestureRecognizer classes Open source implementations of joypad/buttons available
  • 29.
  • 30.
    Part 3: Let’s Makea Game! ..but first we need a story, graphics, music and sfx :)
  • 31.
    KillTime Because he likesto kill paratroopers
  • 32.
  • 33.
    Music & SFX Backgroundmusic, shoot sound, death sound
  • 34.
    Steps for makingKillTime Application Setup Step 1: Adding Background Step 2: Adding Our Hero Step 3: Adding Bad Guys (Game Logic) Step 4: Killing Bad Guys (Adding UI) Step 5: Check for Bad Guy Death Step 6: Animating Our Hero Step 7: Animating Bad Guys Dying Step 8: Adding Body Count Step 9: Adding Sound & Music
  • 35.
  • 36.
    HelloWorldScene.h @interface HelloWorldLayer :CCLayer { // Player sprite CCSprite *_player; // Target and bullet sprite arrays NSMutableArray *_targets; NSMutableArray *_bullets; ! // Body count counter and isShooting flag int _bodyCount; BOOL _isShooting; ! // For body count label CCLabelTTF *_labelTitle; CCLabelTTF *_labelCount; }
  • 37.
    HelloWorldScene.m // Create thenew scene including this layer +(id) scene { ! // Create the scene CCScene *scene = [CCScene node]; ! ! // Create the layer HelloWorldLayer *layer = [HelloWorldLayer node]; ! ! // add layer as a child to scene ! [scene addChild: layer]; ! ! // return the scene return scene; }
  • 38.
  • 39.
    Step 1: AddingBackground (In init) // Get the window size to place elements CGSizewinSize = [[CCDirectorsharedDirector] winSize]; // Add the background image CCSprite *background = [CCSpritespriteWithFile:@"background.png"]; background.position = ccp(winSize.width/2, winSize.height/2); [self addChild:background z:0]; self.isTouchEnabled = YES; _bullets = [[NSMutableArrayalloc]init]; _targets = [[NSMutableArrayalloc]init];
  • 40.
    Step 1: AddingBackground
  • 41.
    Step 2: AddingOur Hero Preload the spritesheet (In init) // Load the sprite sheet CCSpriteBatchNode *batchNode = [CCSpriteBatchNode batchNodeWithFile:@”spritesheet.pvr.ccz"]; [self addChild:batchNode]; // Load the sprites into the shareSpriteFrameCache [[CCSpriteFrameCachesharedSpriteFrameCache] addSpriteFramesWithFile:@”spritesheet.plist"];
  • 42.
    Step 2: AddingOur Hero Add the hero sprite // Add the player sprite CCSpriteFrame* playerFrame = [[CCSpriteFrameCachesharedSpriteFrameCache] spriteFrameByName:@"player1.png"]; _player = [CCSpritespriteWithSpriteFrame:playerFrame]; _player.position = ccp(_player.contentSize.width/2 + 10, winSize.height/2); [self addChild:_player z:1];
  • 43.
  • 44.
    Step 3: AddingBad Guys (Game Logic) Schedule a new target every second (in init) [self schedule:@selector(addTarget:) interval:1.0f];
  • 45.
    Step 3: AddingBad Guys (Game Logic) Create a sprite for the target // Create a new enemy -(void)addTarget:(ccTime)dt { // Create the target sprite CCSpriteFrame *targetFrame = [[CCSpriteFrameCachesharedSpriteFrameCache] spriteFrameByName:@"target.png”]; CCSprite *target = [CCSpritespriteWithSpriteFrame:targetFrame]; // Add the target to the layer and the array ! [self addChild:target]; ! [_targets addObject:target];}
  • 46.
    Step 3: AddingBad Guys (Game Logic) Generate a random x position for the target // Determine where to spawn the target along the X axis CGSizewinSize = [[CCDirectorsharedDirector] winSize]; // Find a random X for the target in the right half of the screen intminX = winSize.width/2; intmaxX = winSize.width - target.contentSize.width; intrangeX = maxX - minX; intactualX = (arc4random() % rangeX) + minX; target. position = ccp (actualX, 320 ); target.anchorPoint = ccp(0, 0); // Determine speed of the target intminDuration = 2.0; intmaxDuration = 4.0; intrangeDuration = maxDuration - minDuration; intactualDuration = (arc4random() % rangeDuration) + minDuration;
  • 47.
    Step 3: AddingBad Guys (Game Logic) Create a move action for the target with a callback when reaching the bottom // Create and run the actions CCMoveTo* moveTarget = [CCMoveToactionWithDuration:actualDuration Position:ccp(actualX,-target.contentSize.height/2)]; CCCallFuncN* actionForTargetMoveDidFinish = [CCCallFuncN actionWithTarget:selfselector:@selector(targetMoveFinished:)]; [target runAction:[CCSequenceactions:moveTarget, actionForTargetMoveDidFinish, nil]];
  • 48.
    Step 3: AddingBad Guys (Game Logic) Add the callback method for a target that dies or reaches the bottom // Method for removing a target that has died or reached the bottom -(void)targetMoveFinished:(id)sender { CCSprite *target = (CCSprite *)sender; [ self removeChild :target cleanup : YES ]; [_targets removeObject:target]; }
  • 49.
    Step 3: AddingBad Guys (Game Logic)
  • 50.
    Step 4: KillingBad Guys (Adding UI) Detect the touch - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // Choose one of the touches to work with UITouch *touch = [touches anyObject]; CGPoint location = [touch locationInView:[touch view]]; location = [[CCDirectorsharedDirector] convertToGL:location]; if (!_isShooting) { _isShooting = YES;
  • 51.
    Step 4: KillingBad Guys (Adding UI) Create the bullet // Create the bullet CCSpriteFrame* bulletFrame = [[CCSpriteFrameCachesharedSpriteFrameCache] spriteFrameByName: @"bullet.png" ]; CCSprite* bulletSprite = [CCSpritespriteWithSpriteFrame:bulletFrame]; bulletSprite.position = _player.position; // Bullet actions CCCallFuncN* actionForRemoveBullet = [CCCallFuncNactionWithTarget:self selector:@selector(removeBullet:)]; CCMoveBy* bulletMoveBy = [CCMoveBy actionWithDuration:1.0f position:ccp(winSize.width, 0)]; [bulletSpriterunAction:[CCSequenceactionOne:bulletMoveBy two:actionForRemoveBullet]]; // Add bullet to layer and array [self addChild:bulletSprite]; [_bullets addObject:bulletSprite]; _isShooting = NO;
  • 52.
    Step 4: KillingBad Guys (Adding UI)
  • 53.
    Step 5: Checkfor Bad Guy Death -(void)update:(ccTime)dt { CCSprite* bulletToRemove = nil; for (CCSprite *bullet in _bullets) { for (CCSprite* target in _targets) { CGRecttargetBox = CGRectMake(target.position.x, target.position.y, [target boundingBox].size.width, [target boundingBox].size.height); // Check if bullet is in the target's bounding box if (CGRectContainsPoint(targetBox, bullet.position)) { // Animate target death and remove target bulletToRemove = bullet; } } } // Remove bullet if target was hit if (bulletToRemove != nil) { [self removeChild:bulletToRemovecleanup:YES]; [ _bullets removeObject :bulletToRemove]; } }
  • 54.
    Step 5: Checkfor Bad Guy Death
  • 55.
    Step 6: AnimatingOur Hero Preload the animation from the spritesheet Adding Player animation in init (In init) // Load the animation for player NSMutableArray *animFrames1 = [NSMutableArray array]; for (inti = 1; i< 11; i++) { CCSpriteFrame *frame = [[CCSpriteFrameCachesharedSpriteFrameCache] spriteFrameByName: [NSStringstringWithFormat:@"player%d.png”,i]]; [animFrames1 addObject:frame]; } [[CCAnimationCachesharedAnimationCache] addAnimation:[CCAnimation animationWithFrames:animFrames1 delay:FRAME_DELAY] name:@"player"];!
  • 56.
    Step 6: AnimatingOur Hero Preload the animation from the spritesheet Adding Kill animation in init (In init) //// Load the animation for villain kill NSMutableArray *animFrames2 = [NSMutableArray array]; for (inti = 1; i< 8; i++) { CCSpriteFrame *frame2 = [[CCSpriteFrameCachesharedSpriteFrameCache] spriteFrameByName: [NSStringstringWithFormat:@"kill%d.png",i]]; [animFrames2 addObject:frame2]; } [[CCAnimationCachesharedAnimationCache] addAnimation:[CCAnimation animationWithFrames:animFrames2 delay:FRAME_DELAY*5] name:@"kill"];
  • 57.
    Step 6: AnimatingOur Hero Animate the hero when shooting (In ccTouchesEnded) // Actions for shooting animation CCCallFunc* actionForShootDidEnd = [CCCallFuncactionWithTarget:self selector:@selector(shootDidEnd)]; CCAnimation* playerShootAnimation = [[CCAnimationCachesharedAnimationCache] animationByName:@"player"]; CCAnimate* shootAnimate = [CCAnimateactionWithAnimation:playerShootAnimation]; [_player runAction:[CCSequenceactionOne:shootAnimatetwo:actionForShootDidEnd]];
  • 58.
  • 59.
    Step 7: AnimatingBad Guys Dying (in update) // Set up actions for animation and target removal CCCallFuncN* actionForDeathDidFinish = [CCCallFuncNactionWithTarget:self selector:@selector(targetMoveFinished:)]; CCAnimate* deathAnimation = [CCAnimateactionWithAnimation:[[CCAnimationCache sharedAnimationCache] animationByName:@”kill"] restoreOriginalFrame:NO]; [target runAction:[CCSequenceactionOne:deathAnimationtwo:actionForDeathDidFinish]];
  • 60.
    Step 7: AnimatingBad Guys Dying
  • 61.
    Step 8: AddingBody Count (In init) NSString* bodyCountString = [NSStringstringWithFormat:@"%d", _bodyCount]; _labelCount = [CCLabelTTFlabelWithString:bodyCountStringfontName:@"Arial" fontSize : 16 ]; _labelCount.color = ccc3(0,0,0); _labelCount.position = ccp(110, winSize.height - 16); [self addChild:_labelCount z:2]; (In update:) _bodyCount++; NSString* bodyCountString = [NSStringstringWithFormat:@"%d", _bodyCount];! [_labelCountsetString:bodyCountString];
  • 62.
    Step 8: AddingBody Count
  • 63.
    Step 9: AddingSound & Music (In init) ! // Start background music, set lower volume SimpleAudioEngine.sharedEngine.backgroundMusicVolume = 0.4f; ! [[SimpleAudioEnginesharedEngine] playBackgroundMusic:@"explosive_attack.mp3"]; (In ccTouchesEnded) // Play sound effect on every shot and on death ! [[SimpleAudioEnginesharedEngine] playEffect:@"shot.mp3"]; !(In update: where the target is killed) ! [[SimpleAudioEnginesharedEngine] playEffect:@"death.mp3"];
  • 64.
  • 65.
    KillTime 2.0 Enemies canmove and attack Joypad Move our hero Different weapons, power ups and health Game menu and high scores Levels Save/Load Game Refactor code (More scenes and layers)
  • 66.
    More stuff toexplore Physics Engines - Chipmunk and Box2D Particle System Tilemaps Menu Interface
  • 67.
    Where can youlearn more Cocos2D Demo Library (Comes with Cocos) Wiki: http://cocos2d-iphone.org/wiki Ray Wenderlich: http://www.raywenderlich.com Steffen Itterheim: http://learn-cocos2d.com Sapus Tongue Source Code: http://www.sapusmedia.com/source
  • 68.
    Thank You! SAALIS UMER