Batteries not Included

http://www.youtube.com/watch?v=GUvDc-xiLC4

Fill Adjacent Modified

I slightly modified the method for calculating when to start filling adjacent pieces.  Before, when a piece went from unfilled to filled, then it would check to see if it had any unfilled neighbors, and begin filling those.  Now, on every update it loops through all unfilled pieces, sees if those have any filled neighbors, and then begins filling if it has a filled neighbor.  This fixes the problem of not filling a wire if it is placed to a neighbor that has already been filled.  A piece will now begin filling instantly if it is placed next to a filled wire.

Since it is now impossible for the flow to ever stop, then only end game conditions now are when 1) all lights are filled or 2)  one of the lights bust.  Limiting the number of end game conditions to two outcomes is a good thing in my opinion.

Batteries Added

Created a GamePieceBattery class, which replaces the need to manually start filling the first wire from the level startup code.  Batteries automatically start filling without being connected to a filled piece.  Batteries also have a constant Elex value, and they do not take the Elex value from surrounding wires.  Could let the player have a limited number of batteries (just one for the earlier stages) and let the player place the battery on the board.  There could also be only special  cells where batteries can be placed on the board.  One thing to think about is if a wire is already filled and a battery is placed next to it with a higher Elex value, then does the wire take the new Elex value of the battery or start refilling?  Removed all starting cell variables from the GameLevel class, since it is now handled by the battery.  Also removed the level fill wait value, since the battery will automatically filling on its own.

Win State

Added a STATE_GAMEWIN state to the main ResistorGame class, so all of the end level logic, display, and music can be handled in that state.  Much easier than making a bunch of special cases in the STATE_GAMELOOP state.  Created a simple victory fanfare theme, which is played after the player completes a stage.  Got bit by not calling SpriteBatch.begin()/end() again.  Need to find a way to run in debug mode under Windows, so I don’t have to spend as much time trying to figure out the cause of game crashes.  I’ve also added a winning victory fanfare melody, but I’m not as happy with it as my title theme or level theme.  It needs some work, or it needs to be scrapped all together.

Screen Abstract Class

Decided to start working on the title screen, to give the player a way to gracefully exit the game without having to press the default Back button.  I realized that the title screen will be using the same button press handlers and drawing methods as the GameLevel class, so I created a Screen abstract class which defines all of the button press and drawing methods as abstract methods.  The GameLevel class has been changed to GameLevelScreen which now subclasses Screen, and I added the override keyword to all the implemented methods.

I’m going to try a new approach for passing controls between screens in the game.  In Java games that I’ve written in the past, I would have to pass a reference of the main class to the specific screen class.  This was really messy, so this time I’m going to make the screen class report the next screen to display through a getter method, eliminating the need to pass and keep track of a reference of ResistorGame in the TitleScreen and GameLevelScreen classes.  I added a protected variable in the Screen class to keep track of the next screen and a method called getNextState.  This method returns -1 to stay on the same screen or a positive integer to move to a different screen, which are the same states defined in the ResistorGame class.  For instance, when the confirm button is pressed on the title screen, it sets the next state variable to the constant for the GAMELOOP state, and then the next call to update in the ResistorGame class will call the getNextState on the TitleScreen object and then appropriately set the state to make the GameLevelScreen the active screen.  By doing this, I was able to take the state logic mess out of the ResistorGame class and I now just have a currentScreen object of type Screen that holds a reference to the current Screen object, so the button press and display methods are just called on currentScreen, and through polymorphism the appropriate implementation of those methods are called based on the subclass.  If I spent some extra time on it, I could probably eliminate the state variable out of the ResistorGame class entirely, and just rely solely on the class type of the currentScreen object.

The title screen has been modified to display three options: New Game, Level Select, and Quit.  The Back button has now been disabled, and the user must select Quit from the main menu to quit the game.

The Level Select currently just allows the user to select a stage level between 1 and 9 using up and down button presses.  For now it doesn’t actually change levels since there is only one level defined.

Winner Winner Chicken Dinner

Win State Added

Each time a piece is filled, the checkWinner method is called which loops through the board array, and returns true if all of the GamePieceLight objects are filled.  Learned that “is” is the equivalent of “instanceof” in Java, which I use to determine if the piece at a given cell is a GamePieceLight type.  Created method to return the number of pieces on the board.  The fewer pieces used, the higher the score.  Created method to return the luminosity of all lights on the board, which is the sum of  the Elex values of all the GamePieceLight objects in the board array.  The higher the value, the more points.  A perfect bonus is awarded if the luminosity value is sum of all the bust values of all the lights.  Added bust instance variable to the GamePieceLight object and added a getter method.  Created drawWinner method which displays the end of level statistics, which the player is graded upon.  I think I’ll just use the classic S, A, B, C leveling system for now, and I will need to set point values for each grade in each level.  The drawWinner method is only called if the hasWon variable is true.  Later, I will also add the level time as a third statistic which the player can earn points.  However, this may not be a good stat since time is somewhat related to the pieces used.

When the user has completed the level, a confirm button press will create a new GameLevel object instance, which will start a new level.  For now, it is just the same level, but in the future the level layouts will be different, and the GameLevel constructor will probably take an ID parameter that determines which level will be loaded.

For the first test, I set the bust values for all the lights to 8, which is the same value as the starting wire.  Therefore, I got a perfect score for just connecting all the lights without any resistors.  Next, I used a few resistors to lower the overall luminosity value.  It correctly returned the sum of the luminosity of all the lights which was 20 (6 for the first two lights, and 4 for the lower two lights), so I didn’t get a perfect luminosity score this time which required 32.

Luminosity and Bust values displayed

Added the bust numbers to the lights in red when the light is not filled.  When the light has filled, the number changes to its luminosity value and is displayed in blue.

Let there be Light (and Sound)

Adding Music

Used Mario Paint Composer to create simple title music and stage music.  It really gives the game a classic feel, and it’s really easy to create great sounding tracks with the tool.  I spent about 30 minutes trying to record the audio from the desktop (tried Fraps, then tried connecting the audio jack output to the mic input), but I couldn’t get Audacity to record even though I saw activity from the mic input in the Control Panel sound control.  Finally, I just held my USB headset mic up against the PC speaker and recorded using Audacity.  The sound is a little muffled, but it does the job for now.  At first, I used Audacity export the music into MP3 format.  I did some research to see what what other formats XNA accepts, because I don’t want to risk the possibility of paying royalties for using MP3.

I’ve never had a formal class in music writing, but I was in the band for many years in high school, so this will be my first attempt at writing music for a game.   The GameBoy icon beeps make a nice sound, but I found that too many of them can get annoying, especially when the song is on a loop.  The GameBoys should be using sparingly, like sprinkles on a cupcake.  I found that the Piranha Plant, Coin, ShyGuy, and Boo make the most soothing sounds, so I’ll probably be using those the most.  On my stage 1 song, I have an intro and four melodies.  The intro has the most GameBoy beeps, then it is phased out in the later melodies.  Using the Arranger in Mario Paint Composer, the sequence I used looks like this:  Intro, Intro, Melody A, Melody A, Melody B (transition), Melody C, Melody C, Melody D, Melody D, Melody C, Melody D, Melody C, Melody D.

 

To be on the safe side, I went ahead and converted my raw music files to WAV using Audacity.  I can convert them to WMA later if needed.  I don’t want to run the risk of having to pay royalties by using the MP3 format.  One trick is that in the IDE you have to change the ContentProcessor of the WAV resource to Song, otherwise it will default to SoundEffect which will cause the program crash when it is played as a Song object.

Adding Lights/LEDs

Created the GamePieceLight class which subclasses the GamePiece class.  Currently, it just overrides the draw method, so that it draws a light (circle sprite) instead of a wire.  The lights are not playable pieces, meaning that the user can not place lights on the game board.  The lights are placed on the board at the start of the level.  Learned that you can’t just simply override a method by redefining it like in Java.  In order to override, the method in the superclass must be declared virtual, and the override keyword must be used when defining the method in the subclass.  After fixing those, I was able to add the light pieces by using the setPiece method in the constructor of the GameLevel class, for each light to be placed on the board.  The great thing about OO (object oriented) programming is that the light automatically inherits all of the properties of the GamePiece class, which was the basic wire.  Therefore, it automatically fills the adjacent wires just as a regular wire does, and its isFilled property is automatically set when the FILL_MAX value is reached.  In order to make these superclass instance variables accessible to the subclass, they must be declared protected instead of private.  This makes the variables visible to subclasses, but not visible to other classes.  Before the light is filled, I use White as the color parameter for drawing the light sprite.  Yellow is used as the color parameter when it is filled.  The maximum “bust” value for the light will be added later.

Adding Resistor Pieces

Added instance variables to the GameLevel class, which hold the currently selected piece and the maximum number of selectable pieces.  The current selected piece is initialized to zero (wire) and the maximum number of pieces is set to two.  In the future, I will just create a list or array of piece types, and derive the maximum value from the array length.  I am currently incrementing the selected piece value when the user presses the action button (default X).  If the selected piece value is greater than or equal to the number of pieces, then it is set back to zero.  In the future, I may have one button specifically for laying wires and another button for placing other pieces like resistors.  Changing the selected piece will also probably be handled by the shoulder buttons.  I have displayed the selected piece index on the game screen for now.  When the selected index is 1, then pressing the confirm button will lay down a 2-resistor.  I made the Elex variable in the superclass protected, so that I can subtract 2 from its value.  A method was created in the GamePiece called pieceFilled which is called when the piece’s fill value reaches the max value.  This method is overridden in the GamePieceResistor subclass, calling base.pieceFilled() first to set the filled boolean values in the superclass.  Then I subtract the Elex value in the sublcass, since that is specific to the GamePieceResistor subclass.  When the resistor is not filled, I use the Gray as the third color value in the blit method, giving the resistor a faded appearance.  When the resistor is filled, White is used as the color parameter which makes it appear brighter.  Currently, there is no check to see if the resistor will lower the Elex value below zero.  I could make it so that the flow stops when the flow gets to zero.

As the screenshot shows, the Elex value is lowered from 8 to 6 as it passes through the first resistor, because the 2-resistor lowers it by 2.  When it passes through the second resistor, it lowers again to 4.