This is Part 2 of a three part behind-the-scenes development series for Wizard’s Tower, my free game for Windows Phone. Part 1 focused on the physics that drive the gameplay. Part 2 will focus on how the levels were created in GLEED2D, a free, generic level editor. Finally, Part 3 will focus on how the animation was created using Anime Studio Pro 8.
First, the download link for Wizard’s Tower.
I also have a pay version here, without advertisements, for .99 cents.
Part 1 of this series already explained the core mechanics of the gameplay, so check that out if you haven’t already. In a nutshell, an animated toon wanders through each level autonomously, and it’s up to the player to manipulate the dungeon around him to get him safely to the exit. Along the way, the player directs the toon to collect coins, rescue goblins, and avoid hazards. All this happens in a physically simulated dungeon using the Farseer Physics Engine (FPE).
Overview Of GLEED 2D
The levels for Wizard’s Tower were designed and created using GLEED 2D. GLEED is a free generic level editor. I’ve mentioned it briefly in a previous article. As a generic level editor, it provides basic transform manipulation (position, scale, rotation) for graphics you drop into the editor. It also has a small set of primitive shapes you can draw into the level and manipulate. These include line paths, rectangles, and circles.
Any level in GLEED is composed of layers. You can put graphical elements and primitives into any layer. Layers can be named, removed, and moved up or down in the draw order.
When you save a level, it gets written in a standardized XML format. The XML file that the editor uses is also the same one that you read into your game. There is sample code available that provides all the methods needed for your game to parse all the layers and elements in your level. You don’t even need to be familiar with the .NET XML serialization methods, because the sample code does the work of parsing the XML file for you.
Since XML is a text format, the saved level file does not contain any of the actual image or primitive shape graphics. Instead, each image element is described by its local filename, a unique name, position in the level, rotation, and scale. Primitive shapes are similarly described by their unique name and basic transforms, including a radius value for circles and a width and height value for rectangles. Line paths are described by a list of Vector2 points that can be read back from the file.
The GLEED code does not draw the level for you, naturally. It only provides a means to read back all the things you put into the level at design time, in the editor. It’s up to you to draw these elements to the screen as you see fit.
How GLEED Was Used In Wizard’s Tower
I created a template to start each individual level from because there are a few things common to all levels: a start position, the exit door, the background, and a level border using line paths.
The level border is an invisible perimeter around the whole level. It’s what Gork (the player’s character) bounces off of when he reaches the edge of a level. When I read the level into my game, I use Farseer’s CreateChainShape method to build a box around the entire gameplay area. In order to read back the Vertices that make up the line path that was drawn in the editor, the first thing that must be done is to grab a reference to the proper Layer.
Layer gleedlayer = level.getLayerByName( “border” );
In every level, the border layer is named “border”, so I use that Name to get a reference to that Layer. Then it’s a simple matter of iterating over every item (Pathitem) in that Layer.
The Farseer CreateChainShape method takes a Vertices object (also a class of Farseer) that contains the list of points that will be used to create a physical boundary in the world. Before calling CreateChainShape, each point in the GLEED level is read back and Added to my locally created Vertices object. Finally, Farseer’s BodyFactory factory class is used to create the chain shape and add it to the Farseer World. Since I need to distinguish what kinds of objects collided during play, I assign the border a Collision Category of Cat1. During play, when Gork collides with an object with a Collision Category of Cat1, I know he just hit the level border, and I turn him around to go the other way.
A level has more than just a border that must be added to the physics engine’s World. The other major items that are simulated by FPE are the platforms and user created bridges.
Just like the border, the dungeon platforms are parsed from the XML file when the level loads.
Again, the GLEED Layer is parsed by first grabbing a handle to the proper layer within the file. In this case, the platform layer is always Named “tiles”. After the Layer is grabbed, I use a foreach loop to iterate through all the items (of type TextureItem) in that layer. I use the name of the actual texture to determine what kind of platform graphic to work on during each loop. In the example above, I’m testing for “floor” and “column” textures. Using the name of the texture, I query my game engine for the dimensions of that texture, since I have several differently sized “floor” textures.
Rectangle texrect = Screen.GetSpriteSource( texname );
Once I have the dimensions, I can again use the FPE BodyFactory to create a properly sized physics object and add it to the World. For floor tiles and columns, I use CreateRectangle to create a simple rectangle collision object for each piece. Notice floor tiles are given a collision category of Cat2 to differentiate them from other obstacles. Since floor tiles can be rotated in the editor, I use FPE’s SetTransformIgnoreContacts method to place and rotate the object after it’s created. The “IgnoreContacts” part of this method does the transform without causing collisions while it’s moved and rotated to its destination values.
Player created bridges are instanced in a very similar manner, except they are dynamically created and destroyed at runtime, instead of being created up-front at level load time. Since bridges can be of any arbitrary length (up to a maximum), the dimensions of the collision rectangle can’t be determined by a fixed texture size, as they are with floor tiles. Instead, I create a rectangle between the start and end points the player touches when creating the bridge on the screen. I use those two points to calculate the angle between them, and then use that angle to SetTransformIgnoreContacts on the collision rectangle that is created with CreateRectangle. When the player destroys a bridge, I just remove that Body from the FPE World.
This concludes Part 2. Join me in Part 3 when I go into the use of Anime Studio Pro 8 to create the animation in Wizard’s Tower.Tweet