Reorganizing Displays

January 19, 2013

One problem that continued to remain was the two different game states for the two display types in the game.  Those two display states are for the 2D sprite based view and the 3d model based view.  These two views shared the same data model, which is a reference to the game world.  However, having two game screen classes still led to some redundant code.  Both Screen states inherited from the ResistorKit.Screen class, which means that the control methods (stick movements and button presses) had to be handled in both Screen classes.  Therefore all of the controls were duplicated in both screens.  Additionally, other things not related to the display code also had to be duplicated, such as the sound effects.

Therefore, I modified the code so that there is only one GameScreen class.  This “new”class has two instance variables, one for the each display type, which are the GameScreen2D and GameScreen3D.  I should have probably renamed those to “Display” instead of “Screen”, since “Screen” implies a state in my game.  I could have also created a “Display” superclass for those two classes, but I thought that would have been overkill, especially since probably only one display method will ever be used in the final game.  I separated the actual drawing code for each display into its respective class.  The screen to be displayed is based on an instance variable in the GameScreen class which is set to an enum value that represents the currently active display type.  This prevents having to keep track of the display state in the main game class, which was the inefficient original approach that I took.

This also solves a long standing problem when exiting the menu screen.  Since the menu screen did not keep track of what screen was before it, the game always returned the player to the sprite based view even when the player was using the 3D model based view.  With the single display class, the player is always returned to the one screen state, which correctly displays the game screen based on the current display method.

I also have the GameScreen overlay displayed in the main GameScreen class, since the overlay should be identical for both the 2D and 3D views.

The only control difference between the 2D and 3D display is that the 3D display allows control of moving the camera when the Right Trigger is held.  That is the only display specific code that needs to be updated in the GameScreen class, and I will fix that in the near future.


I came across a new problem since adding my Jukebox class, which is an AccessViolationException when the program is ended.  This problem was reported in a thread on the AppHub forums, but a definite solution was never reported.  To see if it would help, I added a “Copy for Windows” of the ResistorKit library, and I added a reference in the BlastingBits for Windows project to the ResistorKit for Windows DLL.  However, I still occasionally see this error.



January 15, 2013

I thought I would implement something relatively simple tonight, so I decided to work on audio.  I already have two songs that play for the title screen and level screen, but the logic is built into my main game class which isn’t ideal.

For this game, I decided to take a new approach with the music.  Instead of manually starting and stopping songs when needed, I decided to assign a Song to each Screen class.  When the current Screen is changed, then the music is changed to match that screen.  I may have to make some exceptions, for instance in the case of a boss battle.  The player would still be on the GameScreen instance, but the music would need to change.

To implement this, I added a new Jukebox class to my ResistorKit library.  This will hold the references to all songs and sound effects.  Songs and sound effects are still loaded in the LoadContent method of the main game class, but after each has loaded it is added to the Jukebox object using the addSong and AddSoundEffect methods that I created.  The one drawback is that each Screen needs a reference to the Jukebox.  I can set the Jukebox in the current screen on each call to Update, but I will need to double check in the Screen to ensure that the Jukebox reference is not null before calling any methods on it.  I also created an instance variable in the Jukebox class to keep track of the currently playing Song.  The Song is only changed if the current song instance variable is changed, since there may be multiple screens with the same Song.  Overall, I like this method much better because it keeps the references to all audio objects in one class.  The beauty of this is that a Song identifier only has to be set for a Screen once, and then the music for that screen is automatically played whenever that screen becomes active.

In my main game class, I created an enum called GameSongs which holds identifiers for all of the Songs.  This is much cleaner than all of the int constants that I have been using.  I will want to go back and convert my Texture2D constant int identifiers to enums as well.  The only problem is that my Jukebox class in ResistorKit is not aware of the enum in my game.  I’d rather not put the enum or a reference to it in my library, because that would prevent other projects with different song identifiers from using the library.  I was able to solve this problem by casting the enum identifier to an int when calling the addSong method on the Jukebox object.

After adding the Jukebox to the game and making the necessary updates, I was able to use it to play the sound files.  One issue that I noticed was that since the Attract screen is displayed first, the setCurrentScreen method never gets called since it does not transition from another screen state, so the music wasn’t playing.  As a quick fix, I set the next screen state to the Attract screen in the constructor of the Attract screen, just so that the setCurrentScreen method gets called when it is first displayed.  This change made the music play correctly.  Since the Title Screen has the same Song, the music continued to play without breaking during the transition from the Attract screen to the Title screen which is what I wanted.


Finally, I pulled one of the sound effects from Resistor to use for the gun.  I just needed a temporary sound effect to use to see if the play method for sound effects in Jukebox is working.  I have to say, the Windows Media Player for Windows 8 is really horrible, because it is full screen with no way to change the size.  The Windows 8 music interface forces you to look at a bunch of advertisements from musicians I’ve never heard of and musicians that I really don’t like.  Fortunately, installing Audacity is a really fast and simple process.


One thing that is easy to forget is to set the Jukebox object in the Screen class to protected, so that the objects that subclass the Screen class can use the Jukebox object.  Fortunately, this only has to be set in the library, so the Jukebox will automatically be accessible to any implemented subclass.  Also, it is necessary to set the enum in the main game class to public so that any implemented Screen subclass can reference the sound effect identifiers.  However, the enum does not need to be set to static or constant.

After making these changes, the gun sound effect plays correctly when pressing the fire button.  However, the sound effect would play even if the player does not have a gun equipped and a projectile is not shot.  I would rather not put the sound effect playing code into the model.  I noticed that I already had a LifeTime variable defined in the projectile class, which keeps track of how many frames the projectile has lived.  Therefore, I just added a getter method for that variable, and I play the sound effect if the LifeTime variable is one (first frame).  I moved the code to play the sound from the button press method to the loop that draws the projectiles, and now it only plays the sound if a projectile is shot.  Having the sound play on the first projectile frame will give me the ability to play different sounds based on the projectile type (fire, ice, et cetera), since the projectile is already instantiated.

Texture Atlas

January 12, 2013


After finding the hardware instancing example for XNA, I started working on making a library out of the code so that I could use it in my game.  This wasn’t too difficult, because I just had create a ModelDisplayer class and added methods to pass the GraphicsDevice, data array (block locations), model, bones, and camera information.  Finally, I added a Draw method which displays blocks according to the positions in the data array, using a DynamicVertexBuffer which accepts the Matrix coordinates in its SetData method.  The code is flexible enough to accept any 2D array of row and column positions for the blocks.


After building my new library, I would able to add a reference to it in my BlastingBits game and set my block to set the Instanced Model processor.


As with the SkinnedModelProcessor, it is necessary to build the library for both Windows and XBox 360.  Otherwise, it will return an obscure framework warning which will prevent the library from being used.


The new InstancedModel library seemed to work great in my initial tests, but I found two problems.  First of all, only on the XBox 360 it would randomly throw an error on the SetData method.  I don’t understand all of the technical details, but I did deduce that this error only occurred because I was calling the DrawModelHardwareInstancing method multiple times in my main Draw method.  This was basically running the instance display code three times, once for the blocks in the current room and again for the blocks in the room to the left and right.  Removing the call to display blocks in the adjacent rooms made the error go away on the XBox 360.  Therefore, I combined the block arrays of all three rooms into one array, and then just called the hardware instance draw method only once.


This seemed to work well, but it would not display my own block and texture when I imported my FBX model and PNG texture file.  In the example, it uses an FBX model, but I could never find the associated texture.  My only guess is that the texture is somehow built into the FBX file.  However, I’ve never seen an example of how to load a packed texture from an FBX file generated by Blender, so I’ve always loaded the texture file separately into the Content project.  Therefore, I was stuck with the example block model which had a texture of a cat mapped to it which is unchangeable.


Fortunately, I found a really great article at float 4×4 (no author listed) that explains a similar hardware instancing process called “texture atlas”.  This is even better than the previous code, because it allows textures for a model to be changed at runtime, and it has all the benefits of hardware instancing to eliminate slowdown.  It’s like palette swapping for a 3D model.

I modified the example code to eliminate the random zoom and spinning, so that it displays blocks at X/Y cells, similar to my game maps.  It looks good, but it doesn’t do lighting so I will need to see if it is possible to add that.


As with the previous code, I extracted all of the code specific for rendering into its own library, so that I can link to it in the game.  I only want to handle the loading of the textures in my main game code. This code does not import a model (just draws cubes), so there is no model processor.  I manually updated the vertex location to make the blocks cubes with width, height, and depth of one (-0.5f to 0.5f) Similar to what I did the the previous example, I added a method which takes a 2D array as a parameter, so I can pass the block map to the AtlasDisplay to draw the blocks.  The only thing I wasn’t able to include in the library is the FX Effect file, since it has to go into the content project.  I’m not sure how to include that in the library, unless I create a second library just for that file, which is what I may do in the future.

I setup the new TextureAtlas, Effect, and Texture2D in my main game, and passed the instance of the TextureAtlas to the GameScreen3D class.  I setup all the necessary calls, and eventually I got the new block display using the texture atlas to work.  It now renders the blocks for all three rooms, and I am getting a solid 60 FPS on the XBox 360.  One thing to watch out for is that the code has a variable containing the number of blocks to render, which I currently have set to 1000.  For three rooms, the current maximum number of blocks is 1170 (390 * 3), but most rooms will probably never have more than half of the blocks filled in the room array.  Overall, the update to use the texture atlas method for hardware instancing was quite a bit of work for little noticeable change, but it was better to go ahead and solve the slowness issue now so that it isn’t a problem once I begin designing the levels.

Instanced Model

January 10, 2013

I was feeling good about the progress I have made with the game.  However, one thing I had not tried in some time is running the game on the XBox 360.  When deploying on the XBox, I came across a few problems.  First, the XBox version of the project did not have references to the SkinnedModelProcessor.  After adding a reference, it still returned an error about the library version number.  I figured out that this was because my SkinnedModel project DLL was being compiled for Windows.  In the SkinnedModelProcessor solution, I created a Copy of Project for XBox 360 and added a reference to the DLL created from that in my XBox 360 project instance and it ran correctly.

Unfortunately, I did notice some some slight slowdown on the XBox 360, and the FPS counter usually returned somewhere between 30 and 50 FPS.  I turned off the rendering of the two adjacent rooms, and it went back up to 60 FPS.  This is one reason I don’t like developing on a super powerful computer, because problems like this don’t arise until it’s deployed on a less powerful system like the XBox 360.  After going through my model rendering code, I was able to track down the slowness to the rendering of the “blocks” which make up the game map.  I modified the code so that it renders a block for each map cell, which is the worst case scenario (15 rows * 26 columns = 390 cell blocks).  This significantly lowered the frame rate on the XBox360 to anywhere from 7 FPS to 20 FPS.  The blocks are just six sided cubes with a texture, so the meshes are not complex


After doing multiple web searches, I was able to find one thread that discusses this problem.  This led me to the Instanced Model example code from Microsoft, which is able to display thousands of models at a time with frame rate not dropping below 60 FPS, even on the XBox 360.  I knew there had to be a way to do this, since the graphics processor is capable of rendering thousands of polygons at a time.  From my previous projects in OpenGL, I learned that this is handled by creating a “display list” in OpenGL, so I figured there had to be an equivalent in XNA.

I didn’t have a chance to modify my code according to the example, since my vacation is over and I have limited time to work on game programming.  Hopefully, I’ll have a chance over the weekend to get this working correctly.  Also, I still have the level 2 and 3 armor sets to add to the game.

3D Text

January 6, 2013


Today, I worked on getting the damage numbers to display correctly over each enemy’s head.  As I was working on this, it became apparent that my coordinate system was backwards.  I had noticed this before when I was trying to get the player to move, so I just flipped the sign of the X coordinate of the player.  This was happening because the example I had looked at placed the camera view at a negative Z coordinate.  After reading up more on the XNA 3D coordinate system at Toymaker by Keith Ditchburn, I learned that the positive Z coordinate comes “out” of the screen and the negative Z coordinate goes “into” the screen.  Therefore, my camera should have had a positive Z position value.  I changed this, but now I was seeing the backside of all of my models.  This was because the modification to the SkinnedModelProcessor I made rotated the model by 90 degrees on the X-axis and 180 degrees on the Z-axis.  Removing the Z-axis rotation makes the model face forward, but it is up-side-down.  I had this problem before, which I tried to fix by using a reflection transformation on the Y-plane.  This caused all of the normals to be flipped, which didn’t appear correctly.  After some more trial and error, I found that rotating my model in the processor by -90 degrees (which is the same as 270 degrees) will rotate the model in the correct position.

After fixing the model display, I updated the enemy and player objects to return a Vector3 in a method that returns the position in world coordinates.  This will eliminate the need to do the pixel to world conversion in my GameScreen3D class.  Unfortunately, this pushes it to the “model” classes, which isn’t great either and ideally I would like to convert everything to world coordinates.  However, updating all of the collision detection code will take some time, especially since the XNA Rectangle object doesn’t support floats.

Later, I found another good article by Shawn Hargreaves which explains how to draw text in the 3D world.  The examples were fairly easy to follow, and after some effort I was able to display text values on the screen.  With a little more effort, I was able to get text to follow an enemy on the screen.  His article also describes to to make a billboard, which will display the text facing forward regardless of camera orientation.  I may look into doing that later, along with the sprite optimization suggestions in the article.  However, since the game is happily running at 60 fps I will look into optimizing that later.


Finally, I worked on modeling the third armor set and second enemy.  I just have the models completed thus far, so I will need to go back and find and apply appropriate textures before adding them to my game.

Camera Movement

January 2, 2013

The camera in the 3D game world can now be moved and rotated.

Since I’ve had a few days off from work, I tried to make as much progress as I could with development of the Blasting Bits game.  I was able to get the new model processor working, and now the player model is animated in the game.  In Blender I can make multiple animations/clips, but unfortunately XNA will only allow one animation to be imported as noted in this article by Shawn Hargreaves.  So for now the player model continuously runs.  There doesn’t appear to be any elegant solutions for having multiple animations in an FBX file.

I added camera controls to the game, so when the player holds the right trigger the left thumbstick will zoom and rotate the game world.  Zoom is basically just the distance the camera is away from the game world.  Initially, I had the camera changes in set increments which appeared jarring when changed.  To fix this, I added three variables which are increment, speed, and target for both rotation and zoom.  When the player changes the camera, the increment value is added (or subtracted) from the target value.  Then for each update, the increment value is added to the current position until it reaches the target value.  This gives a much more smoother effect when rotating or zooming.

Custom Model Processor

January 2, 2013

After updating the Skinning Sample project to fix the rotation problem with Blender FBX files, I was able to compile this code into a library.  This library is found in the SkinningSample_4_0\SkinnedModel\bin\x86\Debug directory.  In my main BlastingBits game project, I added a reference to SkinnedModel.dll from that directory, which allows me to make references to the SkinningData, AnimationPlayer, and AnimationClip classes.


After running my game again, I got the ArgumentNullException error from the AnimationPlayer class from the code which checks to see if the skinningData is null.  This is most commonly due to the ContentProcessor of the model being imported not being set to the SkinnedModelProcessor.  Unfortunately, this was not an option for my fullbody5.fbx model which I had imported.  However, I figured out that this can be fixed by adding another reference under the BlastingBitsContent project, which points to the DLL for the SkinnedModelProcessor (SkinningSample_4_0\SkinnedModelPipeline\bin\x86\Debug\SkinnedModelPipeline.dll).  After setting that value, I was successfully able to change the Content Processor of my fullbody5 Model to SkinnedModelProcessor.  Compiling and running the game again resulted in no errors.


In my main game class, I added an instance variable for the AnimationPlayer, which will probably later be changed to a Dictionary to hold all of the animations for all of the models in the game.  In the model load method, I create the AnimationPlayer and AnimationClip for my model.  Then the StartClip method is called to start the animation.  Additionally, the Update method is called on the AnimationPlayer instance variable in the main game update method.


After adding the updated code to draw the player model in my GameScreen3D class, the animated model displayed correctly.  However, when I tried rotating the model 45 degrees, it still displayed but there still appeared to be polygon clipping problems.  After an hour or two of testing different camera positions and angles in both my game code and the Skinning Sample code, I was able to track down that this problem only occurs when a call to SpriteBatch Begin and End is made.  After I found the code that caused the problem, I was able to do a web search and found that this problem has been reported before, and the solution is to set two RenderState boolean values on the graphics device.  When I tried to run that code, it threw an error.  However, I was able to find that error reported and a more elegant solution, which is to set the GraphicsDevice.DepthStencilState to DepthStencilState.Default before rendering the model.  Adding that one line of code before calling the model draw method completely solved the problem with the overlapping polygons in my animated model.

%d bloggers like this: