Light Racer 3D is an exciting project because every day of development adds substantial improvements to the game. The last 2 days have been no exception. Make sure to watch the video at the end of this post. It shows how totally playable the game is. If I were to stop right now, the game would be at least as good as a 3D counterpart to the original Light Racer. As it stands right now, I've got a list of about 20 things I'd like to do for this game to take it from cool to amazing. Because of memory allocation sensitivity on Android, I had to employ a few tricks to deal with the dynamic geometry of the trails. I also ran into a problem getting the explosions properly billboarded.
Day 8 - What was done:
Got text working
synced up game start with OGL init
Serialized ModelData3D into .s3d files - added utilities for developers
Finished all trail rendering including the "falling" trail
Day 9 - What was done:
Got billboard-hacked explosion in (had problems getting bb to work correctly)
Get score text working efficiently
Get level text working
Change touch input to be left-right zone
Added camera turn rate
OBJ file parsing was taking several seconds per file, especially on the racer model. This is because of string parsing, which was hard to do without allocating lots of strings. As you may or may not know, Android is very slow with many memory allocations so reducing those is key to a quick app. I wrote a little tool that parses the obj file and serializes the result to another file. I then added a little utility that reads that serialized file back into the same result. The game now just uses that serialized file and in my tests, it's been 7-8 times as fast. I know I can make something faster but this will do for now.
The trail geometry required a little hack that made it quick to work with. Each segment of trail is held in a class called a TrailSegment. The TrailSegment is simply a list of coordinates to make the path and some state information about the segment, such as, if it is active and how high it's currently standing. Since trail segments are modified, I added the direct buffers to them so that they can hold their own geometry. They have a flag indicating if their geometry needs to be updated, and when the trails are drawn for a player, if that flag is true, the geometry is updated before drawing happens. The last bit of trail, which is from the last turn to the current location of the player, reuses the same direct buffers for all players. The geometry is simple and always uses the same indices, so I simply update the 4 vertices for every draw for every player. It's quick and easy.
I spent about a day trying to get billboarding perfect for the explosion. If you aren't familiar with what billboarding is, imagine a piece of paper lying on the ground. If it's billboarded, no matter where you move to or what angle you look at, it's always facing you. That would be creepy in real life but for games, it's really nice because you can do things like put in a texture-animated explosion, like LR3D has. I'm still bad at linear algebra so I had problems getting the billboard to work correctly, but at the end of the day I figured out a quick hack that would make it work well enough. I'm happy with the hack because, while it's not perfect, it's much less CPU intensive than actual billboarding. My hack is simply to track the rotation and angle of the camera and counter-rotate the explosion quad to match. If the camera is at 30 degrees, the explosion sits at 60. If the camera rotates left, the explosion rotates right. This makes the explosion look fairly convincing from the majority of angles.
There is point sprite function in GL11, but I'm doing the whole game in GL10 to ensure compatibility amongst all devices.
If you're wondering how the nice camera rotation works, here's a bit of code for you:
And finally, here's a video of me playing the game on my G1.