Project Cleanup

blasting_bits_promo

Not much coding was done over the past few days, since I have been working on rebuilding a PC.  I also upgraded my main PC to Windows 8, which required a complete wipe of my primary drive, which means I had to install Visual C Sharp 2010 Express, XNA Game Studio, Blender, Gimp, TortoiseHg/Mecurial, and other programs again.  One issue with installing GameStudio in Windows 8 is that the Games for Marketplace Client must be installed for the Game Studio installer to succeed.

Spent some time cleaning up the project directory.  I got rid of all references to the old game name, so now the name in the repository is now BlastingBits.  Just changing the name required all files in my project directory to be recommited and uploaded to the repository.  Unfortunately, due to the directory structure, my repository had four levels of BlastingBits folders (BlastingBits/BlastingBits/BlastingBits/BlastingBits).  Using the TortoiseHg rename option, I changed it to one level of BlastingBits and the rest in an “src” directory.  Again, the repository saw the moved files as files being deleted and added, so it required a full upload of my entire project directory again.  Not sure if there is any way around that, since I used the TortoiseHg rename option.

After the cleanup, I reimported all of the source files and assets.  The project was still trying to create an executable with the old name, so it was easier to just recreate the project and import the sources.

screen078

One issue that I was able to resolve was the warning about the textures associated with the models.  This is the “Asset was built two times with different settings” warning when running the game.  I figured out that this warning was due to the image being compiled for the model and then again as a regular texture.  I was able to get this warning to go away by setting the “Build Action” option to “None” for the textures used by the models.  This apparently prevents these images from being used as regular sprites in the game.

screen079

I’ve been working on updating the second armor set.  I added some additional changes to the helmet, and I started working on the body piece.  One lesson I learned the hard way is to model both the front and side at the same time.  I only modeled the front at first, so now it is really difficult to model the sides since there are so many vertices now.

Using some of the graphics that I have already created, I made a promotional graphic that I used on my main homepage.  This looks much better than the in-game screenshot that I had before.  I had to render the helmet again in Blender to add the circle plane below with the helmet’s shadow.  One important tip that I learned is that shadow in Blender are only displayed when using a “Spot” light source.  This same graphic and background were also used to update the theme for this development blog.

3D Game World

screen076

I was able to get my models to display on the 3D game screen, and I was able to make it move around using the thumbstick for X/Y axis and the LT/RT triggers for Z axis.  Using an orthographic projection, I was able to make the model appear as a static image.  For now, my screen is mapped to 24×16 game world coordinates, since my player model is only two Blender units tall.  This will be really helpful when converting the game world coordinates to the 3D space, because I should be able to make a 1-to-1 correlation between the 2D bounding boxes and the rendered 3D objects.  Unfortunately, my model still displayed on its side, with the positive Z axis pointing out of the screen.  I spent quite a while playing with the FBX export settings, but I was unable to get it to display correctly.  Then I finally just rotated the model manually in Blender and exported, and still got the same result with the model on its side.  After multiple rebuilds and exports, I finally figured out that the object’s vertices must be rotated in edit mode for the rotation to take effect.  By doing this, I was able to get the player model to display correctly.  It is also important to note that all of the object’s coordinates are in relation to the orange anchor point in Blender, so it is best to move that anchor point to the origin first.  I think it may be better to go ahead and programmatically rotate the FBX object, just in case I get models from another source.  Other models will still have the same problem, and I don’t want to manually rotate the vertices of every model I use.  I also noticed that XNA does matrix operations in order when multiplying.  When rotating an object, it is important to apply the rotation matrix first before translating it.  I haven’t found an equivalent to pushing/popping matrices as in OpenGL.  It is also important to have the model in Blender centered on the rotation point.  This will prevent having to programmatically center it first.

After I got the blocks of the game world displaying correctly, I copied in all of the controller handling code from my existing GameScreen class.  All of the display code from the game objects such as enemies, collectibles, and blocks is the same, except that I have to divide all of the position location coordinates by the tile size (48 pixels) to covert the object’s location from screen coordinates to world coordinates.  The screen coordinates are 1280×720 and the world coordinates are 24×16.  I think the world coordinates are much easier to deal with, since one Blender unit is exactly one unit in the world space.  The only problem is that my collision boxes are Rectangle objects which are handled in screen coordinates.  I can’t convert these Rectangles to world coordinates because the Rectangle only accepts integers and doesn’t handle floats.  I could write my own collision box class and methods that accept floats, but that would be more work to do with no real benefit.  There may be a slight performance improvement, but I don’t think it would be noticeable.  On the other hand, it may be less efficient to do float based collision detection, since floating point operations are generally more expensive.

screen077

Using the models that I generated for the body, hands, boots, and helmet, I went ahead and updated the model on the equipment screen.  Currently, this is just a static image that I rendered by importing all of the armor pieces in Blender.  These pieces complete most of the player’s body, but I will probably need another player model to connect the pieces of equipment.  I’m hoping I can use the bone/armature information from the player to set the armor pieces in real time.  That way a player can have any combination of armor pieces equipped and have it display in real time on their game character.

One other change I made was to pull in all of the “model” (as in MVC) into its own class.  Since the World class already contained the data for the game objects, I used that class.  This just required me to add the Player class into the world class.  The reason for doing this was to have all of the non-graphical game information in one location.  This allows me to pass the “model” to the two different views that I have created, which are the 2D sprite view and the 3D view using the imported FBX models.  Ideally, I should be able to switch between the 2D view and 3D view instantaneously while playing the game, since they are both using the same data model.  I added an interface called GameWorldHandler that just has methods for handling the World object.  This allows me do determine if I should pass the World object to the current screen on each update.  The two game screens and the equipment screen implement this interface, since those require the game World (and the Player object) to display.  However, screens like the title screen and credits screen are not GameWorldHandlers, so those do not implement that interface.  I could have used an abstract class, but those screens already inherit from my ResistorKit Screen class.

helm02_screenFinally, I have started working on modeling the second armor set.  Currently, I just have the helmet done.  I may want to round out the edges some more, but I don’t want to add too may polygon faces because it could possibly impact performance.  Plus, the details of the model won’t be noticeable since the player is so small.  However, the details may be noticeable on the equipment screen where I plan to display the model in full size.

Model Rendering in Game

Today, I exported my Blender helmet model to AutoDesk FBX format to try to get it to render in my game in real time.  The first problem I encountered was that it could not detect my texture.  This was because I was borrowing the texture from the “boot” folder when I did the mapping in Blender.  Therefore, I had to move the texture I  was using in Blender to a “texture” folder at the same level as my exported FBX model.

After loading the FBX model and texture as content items in my project, I created a new Screen subclass which is the 3D display.  Theoretically, this could run concurrently with the existing 2D game screen.  For now, I just created a new main menu item for the 3D game screen.  Using an example from Microsoft, I created a new method in the 3D game screen which renders the model(s).  The model is first loaded in my main game class, then the new model draw method takes the list of models as a parameter.  It also takes the aspect ratio as a parameter, since that is what the example does, but I may remove it or make it a constant later if it does not change.

screen073

Finally, after I finished setting up my model and I ran the program and all I saw was the blue clear color.  Then I noticed a small speck which I first thought was a piece of dust.  This at least let me know that something was rendering, because removing the model drawing code would also remove the black speck.  I think this was because the example code has the camera Z position at 5000f, which I guess was for a really huge model.  Next I tried removing the lines of code in the effects loop for World, View, and Projection one at a time.  By removing all three, I was able to see a rendering of what looks to be the top side of the helmet.  After thinking about it, this makes since because in Blender the Z axis is up, but in XNA the Y axis is up.  Another possible problem is that some of the transformations in the example code look for a parent bone, which I don’t currently have defined for my helmet.

I remembered having to change the export coordinates when exporting my building objects for TetraCity to OBJ format, so that it makes Y up instead of Z.  In the FBX exporter for Blender 2.6, this option is found in the lower left corner of the file save menu of the exporter.  This is really easy to miss if you’re not looking for it, because previous versions of Blender had most options in a popup dialog box.  The fix is made by setting “Forward” to “-Y Forward” and “Up” to “Z Up”.  Selecting “-Y Forward” should automatically set “Z Up”, which is faster because “Z Up” can not be selected with “-Z Forward” selected.  There are also two options for XNA.  I don’t know what these do, but I went ahead and selected them.  Select “XNA Strict Options” should automatically select the other XNA option.  Even with selecting Z Up option, my model was still displaying as if Y is on the horizontal plane.  Either the exporter is broken or my model is not getting updated in the XNA project.  I tried exporting my model to a new filename, and I imported the new model but I still got the same results.  Therefore, the exporter does not appear to be translating the coordinates appropriately for some reason.  Alternatively, I could fix the rotation in code, but that is just one more additional thing to have to do.

screen074

So to get an object moving around the screen, I basically had to go back to step one from three months ago.  I added my helmet object, and added velocity controls to move it up and down.  Once I figure out how to get my current game coordinates to map to 3D space, then I think most of my game world coordinates should translate over with little effort (hopefully).  There also appears to be some tearing with the polygons, which I think may be due to the Z ordering of the faces, because some of the lower polygons will appear above the higher ones.

screen075