The update loop

We already saw a line from the update function where we step the Box2D simulation. Let's now go over the remaining objects that need to be updated:

void GameWorld::update(float dt)
{
  // update the world
  world_->Step(dt, 8, 3);

  // update all game objects
  clown_->Update();
  if(base_platform_)
  {
    base_platform_->Update();
  }
  
  for(int i = 0; i < num_collectibles_active_; ++i)
  {
    ((Collectible*)active_collectibles_->objectAtIndex(i))->Update();
  }

  // update platform if user is dragging one
  if(platform_->isVisible() && !touch_start_.equals(CCPointZero))
  {
    platform_->setPosition(game_object_layer_->
      convertToNodeSpace(touch_start_));
  }

  // walls must move along with clown
  wall_->SetTransform(b2Vec2(0, clown_->GetBody()->GetPosition().y - 
    SCREEN_TO_WORLD(SCREEN_SIZE.height/2)), 0);
  // background must scroll with respect to clown
  background_manager_->Update( has_game_begun_ ? ((clown_->GetBody()->
    GetLinearVelocity().y) * -1) : 0 );

  // game_object_layer_ must move in opposite direction of clown
  // subtract SCREEN_SIZE.height/2 so that clown always stays in centre 
    of the screen
  float position_y = -1 * (clown_->getPositionY() - SCREEN_SIZE.height/2);
  game_object_layer_->setPositionY( position_y > 0 ? 0 : position_y );

  UpdateCounters();
}

The update function of GameWorld calls the Update function for all of its game objects. Then, based on whether or not the user is dragging to create a new platform, the platform_ object's position must be updated. As the clown's body moves vertically throughout the game, so must the left and right walls, and the background environment. Last but not the least, we move our game_object_layer_ object downward as the clown moves upward to ensure that the clown is always in the center of the screen. Basically, we move the camera to follow the clown.

Let's now define the UpdateCounters function from GameWorld.cpp:

void GameWorld::UpdateCounters()
{
  // check if clown has moved higher
  int new_distance_travelled = clown_->GetBody()->GetPosition().y - 
    SCREEN_TO_WORLD(SCREEN_SIZE.height/2);
  if(new_distance_travelled > distance_travelled_)
  {
    // add score for every meter covered
    AddScore(5 * (new_distance_travelled - distance_travelled_));
    distance_travelled_ = new_distance_travelled;

    // add a collectible every 5 meters
    if(distance_travelled_ % 5 == 0)
    {
      // add a rocket or balloon every 100 meters
      AddCollectible(distance_travelled_ % 100 == 0);
    }
  }
}

This function tracks how much distance the clown has covered in meters. Based on this quantity, a distance based score is added. Also, a collectible is added every 5 meters with a special collectible every 100 meters. We are done with the update loop after discussing the clown's Update function from Clown.cpp:

void Clown::Update()
{
  // call parent class' update
  GameObject::Update();
  // store the clown's highest position yet
  highest_position_ = m_obPosition.y > 
    highest_position_ ? m_obPosition.y : highest_position_;

  // if clown has moved two screens lower than highest point, 
    its game over
  if(highest_position_ - m_obPosition.y > SCREEN_SIZE.height * 2)
  {
    game_world_->GameOver();
  }
  
  // update rocket jet stream if it exists
  if(rocket_trail_) rocket_trail_->setPosition(m_obPosition.x - 
    m_obContentSize.width/3, m_obPosition.y);

  // do not update state based on velocity for the following states
  switch(state_)
  {
  case E_CLOWN_BOUNCE:
  case E_CLOWN_ROCKET:
  case E_CLOWN_BALLOON:
    return;
  }    

  // udpate state based on vertical component of linear velocity
  b2Vec2 velocity = body_->GetLinearVelocity();
  if(velocity.y >= 5.0f)
    SetState(E_CLOWN_UP);
  else
    SetState(E_CLOWN_DOWN);
}

The clown's Update function tracks the highest point the clown has reached in terms of screen coordinates into the highest_position_ variable. This value is used to check for the game over condition. Whenever the clown has fallen more than two times the screen height, the game over condition is triggered.

We update the rocket's jet stream particle system if it exists. Now, we must monitor the linear velocity of the clown so that we can set the appropriate state. Thus, if the velocity is above 5 meters per second, we set the state to E_CLOWN_UP and E_CLOWN_DOWN otherwise. However, these states should not be set when the clown is bouncing off the platform or when the clown is holding on to the rocket or balloon, and hence the switch case with return statement.

With that, we reached the end of our fifth game and the first one using Box2D. When you play the game I'm sure you will find something missing. The game in its current state lacks progression. Thus, a user can go on playing indefinitely with nothing to make life more difficult. I urge you to take matters into your own hands. Add some fire to the bottom of the screen! A fire that gets closer to the clown the higher he goes. Miss a single platform and the clown plummets to a fiery fall. That would add a nice bit of challenge to the game, wouldn't it?

..................Content has been hidden....................

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