Adding a game loop and scoring

We have a very nice minigame; now, let us add a game loop and scoring. For the game loop, we will spawn a certain number of objects at different locations, and the player will have to catch the objects. If they catch the object, a point will be added to the score. The final score shown will be the objects caught out of the total objects dropped.

Getting ready

In the MainScene.h file, add the following variables:

#import "cocos2d.h"
#import <CoreMotion/CoreMotion.h>

@interface MainScene : CCNode <CCPhysicsCollisionDelegate>{

  CGSize winSize;
  CGPoint center;

  CCPhysicsNode *_physicsWorld;

  CCSprite *basketSprite;

  CMMotionManager *_motionManager;

  CCSprite *wheelSpriteL, *wheelSpriteR;

  CCPhysicsJoint *motorL;
  CCPhysicsJoint *motorR;


  CCLabelTTF *scoreLabel;
  int score;
  int TOTALSPAWN;
  int spawnCounter;
  bool gameover;

}

+(CCScene*)scene;

@end

The scoreLabel variable will be used to display the score. The score integer keeps track of the score. The TOTALSPAWN integer will retain the total number of objects to be spawned. The spawnCounter variable will keep a count of the total objects spawned. Finally, the gameover bool will check whether the game is over or not.

How to do it…

In the init function, we will initialize all of the preceding variables, as follows:

        score = 0;
        spawnCounter = TOTALSPAWN = 10;
        gameover = false;

Also, we will initialize scoreLabel and schedule a new function that will be called every 2 seconds, as follows:

        scoreLabel = [CCLabelTTF
        labelWithString:[NSString stringWithFormat:@"Score: %d/%d",score,TOTALSPAWN]
          fontName:@"AmericanTypewriter-Bold"
          fontSize: 24.0f];
        scoreLabel.position = CGPointMake(winSize.width/2, winSize.height * 0.9);

        scoreLabel.color = [CCColor colorWithRed:0.1f green:0.45f blue:0.73f];

        [self addChild:scoreLabel];


        [self schedule:@selector(spawnObjects) interval: 2.0f];

The spawnObjects function will either spawn an ornament or a gift at a random height every 2 seconds. So, we will comment out the ornament, gift, and candy stick that we spawn in the init function.

We will then add the spawnObjects function, as follows:

- (void) spawnObjects{

  spawnCounter --;

  float multiplier = winSize.width / 8;
  float xDist = (arc4random() % 5 + 1) * multiplier;

  CGPoint position = ccp(xDist, winSize.height * 0.8);

  int caseNumber = arc4random() % 2;

  if(caseNumber == 0){
    [self spawnGift:position];

  }else if (caseNumber ==1){

    [self spawnOrnament:position];
  }

}

Every time the function gets called, spawnCounter is decremented. We will create two random numbers. The first one is to generate a random x position from which the object will be created. The second random number will decide whether an ornament or a gift needs to be dropped from the position.

We will make changes to the update function as follows:

- (void)update:(CCTime)delta {


  CCLOG(@"spawnCounter: %d", spawnCounter);


  if(spawnCounter <= 0 && gameover == false){

    gameover = true;
    [self unschedule:@selector(spawnObjects)];
  }

  //CCLOG(@"update");

  //CMAccelerometerData *accelerometerData = _motionManager.accelerometerData;
  //CMAcceleration acceleration = accelerometerData.acceleration;

  //CGPoint forceVector = ccp(acceleration.y * 2000,0);

  //[basketSprite.physicsBody applyForce:forceVector atLocalPoint:basketSprite.position];

}

Here, if the spawnCounter variable goes to less than zero and the gameover Boolean is false, we will set the gameover condition to true and unschedule the game's spawnObjects function.

Tip

Make sure you also comment out or delete the code related to the accelerometer as we don't want the basket to move because of it.

Change the collision function to the following so that we can increment the score if the ornament or gift is caught and update the score accordingly:

- (BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair basket:(CCNode *)nodeA   wildcard:(CCNode *)nodeB{

  if([nodeB.physicsBody.collisionType  isEqual: @"ornament"] || [nodeB.physicsBody.collisionType  isEqual: @"gift"]){

    CCLOG(@" collided with ornament or gift");

    [nodeB removeFromParent];

    score++;

    scoreLabel.string = [NSString stringWithFormat:@"Score: %d/%d",score,TOTALSPAWN];

  }

  return YES;
} 

How it works…

With these few changes, we have a small working prototype of a game. Run to see it in action.

How it works…

There is still one last thing to do. We need to set debugDraw to false in the init function. We will run the following code for this:

        _physicsWorld = [CCPhysicsNode node];
        _physicsWorld.gravity = ccp(0,-20);
        _physicsWorld.debugDraw = false;
        _physicsWorld.collisionDelegate = self;
        [self addChild:_physicsWorld];

Enjoy your new physics game in all its glory!

How it works…
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.68.28