Journal
Running Free is my latest candidate to put through Clickteam's XNA runtime! I've settled on this as a first target to complete due to its small size - the entire game is basically made up of just a level selector and gameplay frame that handles everything, so changes only have to be made to a very small area. I was once again impressed by how quickly I could just change the application's build type to XNA for Windows and hit the Export button, going through the level select menu and everything without any problems whatsoever... though the physics of the game were completely broken when I first started it up. After some investigation, I found that this was due to an isolated but fairly severe mathematical error in the expression-evaluating code where the Min() and Max() functions wouldn't return the right values under certain circumstances. (Max(-30, -1.0), for example, is 0 - where were the beta testers!) But having fixed that myself for the time being, and then having fixed a further error caused by me getting the implementation for Min() wrong in a different way when I patched over it, the game ran exactly as it did in the EXE version, and was ready for reworking for the Xbox. One of the most dramatic changes that had to be made was in orientation - Running Free was originally laid out to be viewed on the iPhone vertically, while widescreen televisions are decidedly horizontal. Because programmers are lazy by nature and tend to choose the path that involves the least work now and in the future, I wanted to go with an approach that would let me keep the original level layout file, and just change how I was interpreting it so that the levels were drawn in a different way. True to the laziness theme, I never actually wrote a level editor for this game - the level layout is done on a grid in an Excel spreadsheet, and there's a small Java program that reads it and produces a long string that looks something like: Level=? 322221 6 * 4 6 4 6 4 6 4 322222X 4 6 E! 4 6 4 6* *4 6 4 6 4 6 @ 4 988888888887 ? ...along with a couple of other fields that store the level name, par flips/time, and so on. The game then chews through each character in order and places the corresponding tile at the next horizontal position, starting a new row when it reaches the designated LEVEL_WIDTH. To lay out the level horizontally, the game needed to jump about a bit in the string instead of reading it from start to finish - more specifically, it needs to act as if it's read down the first column (every X tiles, where X is the length of a row) and output it as if it were a row, then start on the next one, like this: And a quick check in Excel gives us the formula MOD(X;5)*3+(FLOOR(X/5;1)) to do this on the 3x5 set of tiles that I mocked up there. Translating this in to MMF is easy enough - you set the "next tile" to point to that instead of just increasing it by 1 each time. Hmm. Well, it would have worked if I had remembered to replace the numbers "5" and "3" in my test formula with the actual width and height of the levels... Which produces this. And this frilly specimen isn't as far off the mark as it might first appear - those little border tiles are represented by numbers in the level string, the number indicating which side of the square to place the border (laid out like a backwards numeric keypad - 3 draws a square on the bottom right, 7 on the top left, 6 with two squares on the right hand side...) To complete the new layout, those sides also needed to be translated. As you can see, this technique doesn't technically rotate the level - it actually mirrors it diagonally. Therefore, I also had to adjust what "initial gravity direction" meant, as well as reversing the flag for telling the game that the player should start running clockwise. (This is fortunate because the first time I wrote the engine, I somehow got the names for "clockwise" and "anticlockwise" consistently wrong all the way through, so you could say that they're now finally correct). And now the re-orientated game runs fine. Work on the interface will come next - it's strange to make the game feel more awkward after the immediacy of touch control, but now everything has to be done without the benefit of a mouse! 2012-10-06 23:42:00 6 comments |