Sunday, March 11, 2012

My int is bigger than your float

Past weeks have been somewhat hectic with a lot of things to do both for AMA studios and the school. Finally I managed to free up some time to get back to working on my game.

The things I wanted to add at this point was the ability to load and unload maps to quickly test various level configurations. But prior to that, I needed some maps.


The key level building thing at this point is to create new elements to control the space where the player can evolve, and thus provide some control over the flow of the game.

Since the player can evolve at two height levels (upper and lower), I started by building some elements that can block the player at each level and force him to change the level if he wants to go further:


On the above picture you can see new barrier elements. Low barriers that are for blocking at lower level, high electric barriers that block at the upper level, and plain high barriers that completely block the player.

Note that I did some quick texture tests in order to see how transparency affects perception.

Now time for editing some levels with these new elements:


Ah,  I've had one tremendously annoying issue with the wall tiles. I needed to be able to turn them by 90 degrees. Fortunately Tiled just implemented that feature in one of its latest release...but...

Tiled encodes the rotation and flipping of a tile in its 4 most significant bits of the 32 bits integer tile index. Sounded fair enough until I realized that lua did not have enough precision with its 32 bits float (24 bits mantissa) to correctly interpret that data when converting from int to float (lua doesn't handle int). Unless you're working with double, you can't get a correct 32 bits integer converted into floating point. And on consoles we don't use double yet.

EDIT: Also I forgot to mention that there's no bit-wise operation in lua 5.1 anyways, I think that's something coming up in the next release.

So I came up with a rather twisted solution:

When parsing the xml file, I save the tile index as a string (I do not convert it from the file into a number).
Then I send the string to a C++ function that converts is back to int (actually a long integer) and then figures out the tile rotation based on the aforementioned most significant bits. It looks like this:


IA::tile IA::unpackTile(const char *tileID)
{
IA::tile currentTile;


unsigned long rawID = strtoul(tileID,0,10);
currentTile.id = rawID & 0x0fffffff; //mask rotation and flip info stored in the 4 most significant bits
int rotID = rawID >> 30; //keep only 2 most significant bits where the rotation info is stored
if (rotID == 0) currentTile.rot = 0;
if (rotID == 2) currentTile.rot = -90;
if (rotID == 3) currentTile.rot = -180;
if (rotID == 1) currentTile.rot = -270;


return currentTile;
}


Alright, now I've got my tiles with the right orientation, time to test some levels.

To choose the level to test, I need some menu. So while I was at it, I implemented a menu system that is completely data driven and allows me to add menu hierarchy and content in a simple lua table.


The first menu structure implements some basic states of the game, like Main Menu; Play; Pause; Game Over; Retry and Restart.

Here you can see the menu that pops up when the game is paused in the middle of an explosion (by pressing Start button) :


On this screenshot you can also see some of the barriers that forces the player to go to the upper level and confront the mines if he wants to grab the blue bonuses.

Next: life, shield and fuel management, and HUD


No comments:

Post a Comment