Generating a world using data exported from RUBE

RUBE exports its level information in a neat and tidy JSON file. We can create a complete physics world from this exported JSON file by using a JSON parser along with a class called b2dJson. You can find the required files in the RUBE download package as well as in the source bundle for this chapter.

Before we go ahead, let's discuss how our Box2D world will be created for this chapter. We will split the world creation into two main functions: CreateWorld and CreateGameObjects. In the CreateWorld function, we will use the b2dJson class to create a b2World object, based on data exported from RUBE. In the CreateGameObjects function, we will create sprites for all the physics bodies within the world.

Without further ado, let's begin with some code. This is the CreateWorld function from GameWorld.cpp:

void GameWorld::CreateWorld(b2dJson* json, int level)
{
  // get file data and parse it to get b2dJson
  char buf[32] = {0};
  sprintf(buf, "Level%02d.json", level);
  //sprintf(buf, "testing.json");
  unsigned long size;
  char* data_uc = (char*)CCFileUtils::sharedFileUtils()->
    getFileData(buf, "rb", &size);

  // error message
  std::string msg = "could not load file";

  world_ = json->readFromString(data_uc, msg);
  // tell world we want to listen for collisions
  world_->SetContactListener(this);

  // delete char buffer
  delete data_uc;

#ifdef ENABLE_DEBUG_DRAW
  debug_draw_ = new GLESDebugDraw(PTM_RATIO);
  world_->SetDebugDraw(debug_draw_);
  uint32 flags = 0;
  flags += b2Draw::e_shapeBit;
  flags += b2Draw::e_jointBit;
  debug_draw_->SetFlags(flags);
#endif
}

The CreateWorld function is called when GameWorld is created, and takes a pointer to a b2dJson object along with the level number. In this function, we generate the name for the respective level file and use the getFileData function from CCFileUtils to read the file's contents.

We then pass the file data into the readFromString function of class b2dJson, which will return a pointer to a newly created b2World object. This is how simple it is to generate a physics world using the data exported from RUBE. We wind up this function by setting GameWorld as the contact listener and setting up debug draw like you've seen in previous chapters.

The b2dJson class provides an extensive set of functions that can be used to query almost everything related to the physics world it created using the data exported from RUBE. We will use some of the functions to save references to a few relevant bodies and extract the custom properties we set in the editor.

Let's take a look at how this is done in the CreateGameObjects function from GameWorld.cpp:

void GameWorld::CreateGameObjects(b2dJson* json)
{
  // save references to a few important bodies
  boundary_body_ = json->getBodyByName(string("ground"));
  catapult_body_ = json->getBodyByName(string("catapult"));
  catapult_joint_ = (b2RevoluteJoint*)json->getJointByName(
    string("catapult_joint"));

  // extract the list of fish (comma separated string) for this level
  fish_list_ = json->getCustomString((void*)world_, 
    "ListOfFish", "");

  // get all bodies from the world that have a sprite name 
    i.e. GameObjects
  b2Body* body_in_list = world_->GetBodyList();
  while(body_in_list != NULL)
  {
    string sprite_name = json->getCustomString((void*)body_in_list, 
      "SpriteName", "");
    if(sprite_name.compare(""))
    {
      // append file extension...sorry we don't have 
        spritesheets at the moment! :(
      sprite_name = sprite_name + ".png";

      // see if this game object is a cat
      if(json->getCustomBool((void*)body_in_list, 
        "IsCat", false))
      {
        // create the Cat
        Cat* cat = Cat::create(this);
        // save the body
        cat->SetBody(body_in_list);
        // add & save this Cat
        addChild(cat, E_LAYER_CATS);
        cats_.push_back(cat);
        ++ num_cats_;
      }
      else
      {
        // create the GameObject with the respective 
          sprite name
        GameObject* game_object = GameObject::create(this, 
          sprite_name.c_str());
        // save the body
        game_object->SetBody(body_in_list);
        // add & save this GameObject
        addChild(game_object, E_LAYER_OBJECTS);
        game_objects_.push_back(game_object);
        ++ num_game_objects_;
      }
    }

    // continue checking
    body_in_list = body_in_list->GetNext();
  }

  // reorder catapult to be above the fish
  reorderChild((CCSprite*)catapult_body_->GetUserData(), E_LAYER_FISH + 1);
}

The CreateGameObjects function is called when GameWorld is created, and accepts a pointer to a b2dJson object. We begin by storing references to the bodies of the ground and the catapult, followed by a reference to the catapult's b2RevoluteJoint object.

We then extract the world's custom property with the name of ListOfFish by calling the getCustomString function of the b2dJson class. This function accepts a void* object, so we can use this very function to get the custom properties for our b2Body objects as well. This will return a std::string object that we will use when creating the set of Fish objects for a particular level.

We then iterate through the list of bodies, looking for bodies that possess the SpriteName custom property; this will tell us which bodies need GameObject objects created. Within this loop, we also compare the value of the IsCat custom property by calling the getCustomBool function and, passing in the current b2Body object. If this value is true, we create an object of the Cat class; otherwise, we create an object of the GameObject class. We also add the object created to the respective list belonging to the GameWorld class. To wind up the CreateGameObjects function, we reorder the catapult's sprite so that it is rendered on top of the fish.

Now that we have created the game's physics world and all the GameObjects, using the data exported from RUBE, we can define the behavior of the different kinds of fish.

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

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