Sunday, May 8, 2011


My hour of darkness and tribulation came to an end this morning, as I finally got all my tiles detecting the player. I started from the premise that since I was already drawing individual tiles to the screen, somewhere in my game I was already detecting and making use of information about the size and position of each tile. Since my Intersects() function takes two Rectangle objects, I knew I needed to get a rectangle for each tile with this info in it. I added a blank Rectangle object called "boundbox" to the definiton of the Tile constructor, so now every time a tile was brought into being it was given a blank rectangle. Then I went into the loop where it loops through every potential tile placement on the screen and determines whether there is a visible tile there, according to the Dictionary object that reads that info from the level.txt file. In that little chunk of code inside the loop where, for each individual tile, the game assigns it a position and a texture, I just added an instruction for the game to fill up that particular tile's  "boundbox" with the relevant information before moving on to the next tile. Pass each tile's rectangle and the player's rectangle into the Intersects method every time we cal Update, and pow, suddenly we're in business.

Even in this trivial piece of code(against which I banged my head for the better part of two weeks) there are already things I see as being wrong that will have to be fixed. Let's make a bullet list:
  • The first obvious blunder I found testing it is that my method for extricating the player from a block he has sunk into is not very elegant. Basically if he's coming from underneath (player.IsJumping) I increase his Y value until he's out of it, and if he's approaching from the top (player.IsFalling), I drop his Y value until he's standing on the block. Looks great in most cases, but if you time your jump right and hit a mid-air block from the side, you get a popping effect as the player is suddenly repositioned above or below the block. The refactor is to do it the way it's done in the XNA example platformer, which I still haven't wrapped my head around, it somehow gives you the depth and direction of a collision between rectangles, so you can just push the player back in whichever direction he entered, however far you need.
  • There are a lot of places where, inside a loop, I'm calling some property of the Tile class or doing some fugly piece of math, many many times a second. Instead I should give the method some member variables that create all the necessary values before running the loop, and then just plug those unchanged values in rather than flipping them around at high speed. This is the kind of thing the Big Orange Book is teaching me about performance!
OK maybe two bullets is enough there, I could go a while listing the problems with what we already have, including the jump itself, which has no power curve and isn't timed in the way the walk is, which will probably cost me down the line. But today is not a day for worry and pessimism! Today I have swung the silver sword of the game programmer, and lopped off one of the hydra's heads. Surely this hydra isn't going to grow a bunch more heads overnight, right?

Next steps: Doors and Death

No comments:

Post a Comment