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?
3.128.198.59