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.
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.
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.