Thursday 9 February 2012

Out With The Old... Part One

As mentioned in my last post over the past month I have pretty much scrapped what I had developed for my platformer and re-designed and re-developed it into a code base that I'm much happier with. Of course, it's not all perfect as there are still some bugs to work out. But I'm at a stage where I'm much happier.

This following post will hopefully give a bit more insight into what's changed on the back end, so the experienced developers can see the pitfalls that I fell in originally and hopefully the new developers can see the pitfalls to avoid. So lets get started.

What's Changed

The Removal Of Individual Textures
How It Was: When I first started developing my plaformer, I was on a coding spree. I was developing new tiles that had different purposes in the game. I had ground tiles that the player walked on, sign post tiles that the player read, collectable tiles that the player, errr, collected. You get the idea.
Each of these tiles had an associated texture (or textures for some things like ground) and each of these textures were seperate files. Now the seasoned developers can see the problem here, and for those that don't you have to understand the way that the graphics device (or possible spritebatch) works. One of these components will batch all calls made with a given texture and process the work load. The fewer batch calls that have to be made, the less work the graphics processor has to do, which results in better frame rates (to a certain extent).

How It Is Now: Following advice that I saw countless times but ignored in the AppHub forums, I decided to put all of my tile textures into a massive texture, also referred to as a sprite sheet. This resulted in less batch calls to the graphics device and helped improve my frame rate problem. In order to achieve this I had to improve my internal base Sprite class to support displaying of areas of a larger texture (now referred to as TextureBoundingArea), but this was a small change. I also had to change the way my texture manager worked, but this was getting changed anyway due to the following problem...

Updating My TextureManager To Be More...Flexable
How It Was: One of the goals of mine was to have multiple textures for given tiles like the ground, but then to also have a number of effects I could apply to that texture to make it appear different but be the same texture. This was done via the texture manager and each tile had a number of different effect collections. These effects only consisted of the in-built SpriteEffects and rotations at 90 degree intervals. The problem came to how I was defining these effect collections. Originally I was defining them in code in a static constructor. While this isn't necessarily a problem, I was finding it one as the code was getting unmanageable the more tiles I added, so I decided to change it.

How It Is Now: My TextureManager has had a rewrite and now contains effect collection information (as well as texture locations) for each tile type in an Xml file. This meant that all initialsing data was seperate to the code (as it should be) and could be easily edited with help of an XML schema. This information is then loaded when a level loads and is stored against the type of each tile. This is done by having a node in the XML that is the name of the tile, for which I use the Type.GetType method passing in the value in the XML node.

Seperating Visual Texture Information From Collision Texture Information
How It Was: The collision system I use for the game is a combination of Axis-Aligned Bounding Boxes (AABB) and Pixel-Perfect-Collision (PPC). This is where collisions between the player and the suspecting tile are checked first against each other bouding boxes. If an intersection appears between them (i.e. where the two boxes cross), PPC is then performed when the overlapping of two texture pixels are checked. The reason this is done is because PPC is an expensive process and only needs to be done when we are 90% sure a collision has occurred. The code for this method was taken from the AppHub where they provide an excellent example (one I even believe has been stolen and made into a WP7 game). This resulted in me having a texture that represented the tile visually as well as being used for collision code. This presented some limitations in my tile design and meant I couldn't do nice visual things like having grass from a ground tile cover the players feet.

How It Is Now: I now have two sprite sheets in my game. One sprite sheet represents the visual-ness of the tiles (now with grass on the ground tile) which can have the visual effects mentioned earlier applied to them. The second sprite sheet represents the collision texture which is used for collision detection and is stored, like the effect collections, against each Tile type. The TextureBoundingAreas then match across both sprtesheets so I only have to define the area once in the XML document. The result of this is two fold; a) I can add visual flair to the visual textures like my wanted grass and b) I can increase the collision area of a tile so that a collision occurs before the player collides with the visual texture (like for an interactive item).

That's it for part one. I'll try and write up part two which will include more changes, some additions and a few things yet to be implmented. Have a good weekend.

No comments:

Post a Comment

Got an opinion? Who hasn't? Post it here...