Create Your Own Level Editor: Part 1/3

In this tutorial, you’ll learn how to make a level editor for the Cut the Rope clone that was previously covered on this site. Using the level editor you can easily make new levels. All you have to do is drag and drop the ropes and pineapples to where you like them. By Barbara Reichart.

Leave a rating/review
Save for later
Share
You are currently viewing page 6 of 6 of this article. Click here to view the first page.

Displaying Your Pineapple Objects On-screen

Your level-loading code will replace the current hard-coded game implementation in order to create a playable game scene from the information in the XML file.

Since the hard work has already been done, all you need to do at this point is to iterate over the loaded level information and create a physical body for each pineapple and rope contained in the scene.

Sounds easy, doesn’t it? :]

Start by adding some more imports to the top of CutTheVerletGameLayer.mm:

#import "PineappleModel.h"
#import "RopeModel.h"
#import "CoordinateHelper.h"

Okay, pineapples — enter stage left!

In CutTheVerletGameLayer.mm, replace all the code between the two #warning lines (including the two #warning lines themselves) in initLevel with the following:

    NSMutableDictionary* pineapplesDict = [NSMutableDictionary dictionary];
    for (PineappleModel* pineapple in levelFileHandler.pineapples) {
        b2Body* body = [self createPineappleAt:[CoordinateHelper levelPositionToScreenPosition:pineapple.position]];
        body->SetLinearDamping(pineapple.damping);
        [pineapplesDict setObject:[NSValue valueWithPointer:body] forKey:[NSNumber numberWithInt: pineapple.id]];
    }

In the above code, you first create a dictionary that will contain all the pineapple bodies.

Why would you do this, when you already have the pineapple data stored elsewhere? Think ahead for a moment. After loading and displaying the physical pineapples, you’ll need to connect them with the ropes.

To do this, you’ll need to know the body that represents the pineapple, so it makes sense to temporarily store them in a dictionary, where the key to each body is the pineapple’s ID.

In order to create a body for each pineapple, iterate over all of the pineapple models in the file handler. For each pineapple, create a body and set its position. Calculate the screen coordinates from the relative level coordinates by calling levelPositionToScreenPosition.

Next, the damping property is set. Finally, you add the newly created body to the dictionary.

All the pineapples are now loaded and should show up at their respective positions.

Build and run your project. Your game fires up, the pineapples display on the screen and…

Uh oh. You expected your game to make a splash — but not literally! The pineapples aren’t staying in the trees, as seen below:

Pineapples falling down like a boss

If you think about it, you probably should have expected this result. Gravity is acting on the pineapples, but there aren’t any ropes to hold them in position!

Time to tie this one off by adding some ropes! :]

Displaying Your Rope Objects On-screen

Add the following code to CutTheVerletGameLayer.mm, just after the code that loads the pineapples:

    for (RopeModel* ropeModel in levelFileHandler.ropes) {
        b2Vec2 vec1;
        b2Body* body1;
        if (ropeModel.bodyAID == -1) {
            body1 = groundBody;
            CGPoint screenPositionRopeAnchorA = [CoordinateHelper levelPositionToScreenPosition:ropeModel.anchorA];
            vec1 = cc_to_b2Vec(screenPositionRopeAnchorA.x, screenPositionRopeAnchorA.y);
        } else {
            body1 = (b2Body *)[[pineapplesDict objectForKey: [NSNumber numberWithInt:ropeModel.bodyAID]] pointerValue];
            vec1 = body1->GetLocalCenter();
        }
        
        // TODO: Mysteriously, the second connection is missing. Can you create it?
        
        [self createRopeWithBodyA:body1 anchorA:vec1 bodyB:body2 anchorB:vec2 sag:ropeModel.sagity];
    }

This loops through the rope model objects and fills in the body1 and vec1 values for the rope’s first anchor point, depending on whether the rope is tied to the background or tied to a pineapple.

The code looks pretty good, but what’s with that TODO note? The code above only implements a single anchor point — it’s left to you to determine how to implement the second anchor point.

If you aren’t sure how to do this, go through the code for creating the first anchor point step-by-step.

To set up an anchor you need two things: a body to attach to, and a vector which indicates the position of the anchor point.

You have to distinguish between two cases for your second anchor point.:

  1. Body ID is -1: this means that the rope is tied to the background and you need to convert the anchor point coordinates stored in the model class to determine its location. Don’t forget to convert the level coordinates to screen coordinates.
  2. The rope is tied to a pineapple: Get the b2Body out of the pineapple dictionary and use its center for the anchor’s position.

Okay, don’t panic — if you’re really stuck, the complete spoiler code is below. But give it a go before you give it up! :]

[spoiler]

        b2Vec2 vec2;
        b2Body* body2;
        if (ropeModel.bodyBID == -1) {
            body2 = groundBody;
            CGPoint screenPositionRopeAnchorB = [CoordinateHelper levelPositionToScreenPosition:ropeModel.anchorB];
            vec2 = cc_to_b2Vec(screenPositionRopeAnchorB.x, screenPositionRopeAnchorB.y);
        } else {
            body2 = (b2Body *)[[pineapplesDict objectForKey: [NSNumber numberWithInt:ropeModel.bodyBID]] pointerValue];
            vec2 = body2->GetLocalCenter();
        }

[/spoiler]

Build and run the game and you should now be able to feed the crocodile. That poor animal has probably been starving, waiting for the level to be finished! :]

If you have done everything correctly, the level should play identically to the original hard-coded version. The major difference is that now you can simply edit the XML file, restart the game and a slightly different level layout will show up!

Where to Go From Here?

Here is a sample project with all of the code from the above tutorial.

Take some time and freely edit your XML level file to try out as many combinations of pineapple and rope placements as you can think of. Right now, the level editor only gives you the ability to load existing XML files — you can’t actually edit them yet. It’s more of a level “loader” than a level “editor” at this point.

Don’t despair — the second part of this tutorial is all about getting the editor working, and allowing you to edit levels live on your device!

Barbara Reichart

Contributors

Barbara Reichart

Author

Over 300 content creators. Join our team.