Freeze Gun

October 30, 2012

Added the first gun socket tonight, which is the freeze gun.  First of all, a freeze variable was added to the enemy.  I represented this as an integer, which is zero if the enemy is not frozen.  When the enemy is frozen, then that variable is set to the number of frames that the freeze will last.  On each enemy update, the freeze value is decremented if it is greater than zero.

I added a method that returns true if the frozen value is positive.  This is used in the GameScreen class to determine if the enemy should be drawn frozen.  For now, if an enemy is frozen then it is drawn with a blue shade.  In the EquippedSockets class, I created a method to flip the zero gun socket between None and Ice when the confirm button is pressed when the gun is selected.  I’m starting to think about removing the two gun (zero and one) concept from the game, because it may make the game too complex with the socket system.

The projectile class was also updated to include a boolean to indicate if the pellet has the ice attribute.  If the ice gun socket is equipped and the gun is shot, then the ice boolean for the projectile gets set to true.  I created a simple diamond shape in Gimp to represent the ice projectile.  I’ll work on the graphics later, but this will at least let me know if the ice projectile is correctly shooting.

I’m going to leave it at that tonight.  Sorry, no videos this time.  I think I’ll hold off on those until I have something a little more impressive to show.  The ice gun functions correctly and properly freezes enemies, but one change I may make is the ability to land on enemies that are frozen, so they can be used as stepping stones.  Currently, frozen enemies will still hurt the player.


Eight Way Shooting

October 26, 2012

Added eight way shooting to the game, so that the player can aim vertically as well as horizontally.  Pressing up will set a flag that keeps track if the player can shoot upward.  When looking upward, then the Y velocity is set to the projectile speed.  If the player is not walking, then the player should shoot directly up, so the projectile’s X velocity is set to zero.  If the player is walking, then the projectile will move diagonally up/left or up/right depending on which way the player is walking.  I don’t have graphics for the player lookup up or down yet, so for now it just displays “looking up” or “looking down” over the player’s head.  One feature I plan to add is making the player aim diagonally up or down when the left or right trigger is pressed.  However, that will require an update to ResistorKit to handle those inputs, as well as adding methods in the ResistorKit screen class.

I went back and modified the velocity for the up/right and up/left shots, since it will actually go slightly faster than the projectile moving directly vertically or directly horizontally.  Currently the projectile speed is set to 10, so that it moves 10 pixels each second.  When shooting diagonally, the projectile will actually move 14.142 pixels according to the Pythagorean theorem ( square root of (10 squared plus 10 squared) ).  To make the diagonal speed match, the values of the X and Y components can be found by dividing the projectile speed by 1.414 (or multiplying by 0.707) which is the square root of two.  This is because Sqrt(1^2 + 1^2) = Sqrt(1 + 1) = Sqrt(2).  Fortunately, finding the length of the two sides (projectile’s X and Y velocity) of the triangle from the hypotenuse just requires multiplying by a constant.  I believe this is because the two sides of the right (90 degree) angle are equal, but I don’t have any formal proof of this.  If I allowed precision aiming where the X velocity was not equal to the Y velocity, then more complex calculations would probably be needed.

The projectile collection class has been modified to handle more than one projectile using a List.  A projectile is removed from the projectile from the List whenever it is inactive.  The alive flag now indicates that the projectile is ready for removal from the collection.  This may be slightly inefficient, since it is allocating memory for a projectile each time one is shot.  I may revisit this later if there are performance issues.  One problem is that I couldn’t just simply increase a counter variable to loop through each element and delete it if it is inactive, since that will modify the structure of the List which could result skipping elements if not careful.  Therefore, I looped through the List in reverse starting at the List size minus one and going down to zero.  That way if I delete an element then it will not effect the iterator.

Similar to enemies, I added code to handle passing a projectile from one room to the next.  I removed the condition that if a projectile hits the room boundary, then it disappears.  One interesting side effect is that now the projectile will live forever if it does not collide with an enemy, so it will loop forever as long as it is in the player’s room or an adjacent room.  Therefore, I added a variable to track the lifetime of a projectile, which I currently have set to  60 frames.  This may be upgradeable in the future with a socket.

Finally, on each projectile update I now check to see if the projectile has collided with a block.  This uses the same collision method that I created in the map class to do the enemy collision.  If the projectile has collided, then I set the alive flag to false, which will mark it for removal from the projectile list.  I also added the player’s width to the starting position of a projectile when shooting right, that way it doesn’t look like the projectile is going through the player’s body.

Socket System

October 24, 2012

Socket system allows special abilities to be assigned to equipment.

I decided to scrap the magic based system for a socket system instead.  Currently, I plan on having five socketable pieces of equipment, which are the helmet, zero gun, one gun, body armor, and boots.  For now, I only allow one socket for each piece of equipment, but I believe I will be able to expand that in the future in some cases.  Some abilities may conflict with others, so I will need to limit what combinations can be used.  A new socket equip screen has been added to allow the player to assign a socket for each piece of equipment.

The helmet sockets will enable visual items such as night vision (to see in dark places) and enemy information.  The zero gun and one gun sockets will modify how the guns work, such as modifying recoil rate and projectile trajectory.  The body armor socket will expand the player’s health and defense.  The boot sockets will modify the player’s jumping ability.  I may also add a hands socket, which will allow the player to hang and climb on walls.

The boot socket is the only one I currently have implemented.  The player can choose between four socketable abilities, which are Jump +1, Jump +2, Jump + 3, and Double Jump.  The three jump abilities will increase the player’s jump height.  The Double Jump ability will allow the player to jump again before touching the ground.

Level Editor Update

October 20, 2012

The level editor now supports multiple rooms.

Game Menu

Added a GameMenu class to ResistorKit, since that is a feature that I commonly use on many screens.  The GameMenu class keeps track of the set of menu items and which item is selected.  It handles rotating the selection back to the top when down is pressed on the last item or selects the last item when up is pressed on the first item.  This way I don’t have to rewrite this code on each screen that has a menu.

I expanded the menu system to draw the menu at a given position using a specified font, which are passed as parameters.  The text color and highlight color can be set using the appropriate method calls.  The spacing between menu items can also be set with a method call.  One feature I would like to add is passing the menu item action as a function parameter for each menu item, but the C Sharp way for passing function/method parameters wasn’t clear to me.  I did find some documentation on using Func or delegates, but I don’t want to invest time in figuring those out now.  Therefore, executing the action must be handled on the game screen using the getSelectedItem method that I created to return the index of the currently selected menu item.

The title screen has been updated to use the ResistorKit GameMenu class, and it takes advantage of the text and highlight color setting methods.  Currently, default text is black and highlighted text is green.

Level Editor Modifications

Updated the level editor so it now supports multiple rooms.  When the level editor is started it creates a default room that is the head of the list of rooms.  Pressing A will add a block to the room.  Pressing RB will add a new room to the end of the list.  Pressing start will add all created rooms to the game world.  Currently, a room can’t be edited once it has been added, but that is a feature I plan to add.  I will also need to add a method for navigating through the currently created maps.  Then I will probably make RB create a room to the right and LB create a room to the left of the currently selected room.

A preview of all levels is now displayed at the top of the level editor screen.  This preview expands as new rooms are added.  The room ID is also displayed in the upper right corner for each preview, but I may remove that in the final release.

Enemy and Jumping Updates

October 17, 2012

Jumping now uses acceleration and looks less linear.  Enemies now move across room boundaries.

Library Update

When developing a library, one important thing to remember is to make your classes that should be accessible in the API public.  By default, classes are created with no scoping.  You will not be able to access any classes in your library, until those are declared public.  Tonight, I added some of the methods I used for drawing raised text in Resistor to the ResistorKit library as static methods in a Graphics class.


After reading about how others have implemented jumping, I decided to scrap my current linear method which is based on subtracting a constant value for a set number of updates.  That resulted in a constant jump speed and fall, which looks very angular when moving at a constant speed.  To fix this, two float acceleration variables have been added for jump and fall acceleration.  I could have probably used just one acceleration variable, but I thought breaking it out into two makes the code more readable.  When the player jumps, this acceleration value gets set to a constant which is the jump power.  This acceleration value gets subtracted from the player’s Y position on each update, which increases the jump height on each update.  Also on each update, the acceleration value is decreased by a constant value.  Therefore, the player’s jump acceleration decreases until it reaches zero.  At that point, the player’s falling variable gets set to true and a similar process occurs with the falling acceleration.  The only difference is that the falling acceleration continually increases so it relies on collision with a block to stop the fall.  I also added a terminal velocity value, which the acceleration can’t exceed.  Right now that won’t make much of a difference in my game since it doesn’t scroll vertically, but if there was a long fall then not having a terminal velocity would make the player impossible to control while falling.

Enemy Updates

I updated the Enemies collection so that a map can now correctly handle multiple enemies.  I also added a method in the Map class to move an enemy from one map collection to another.  This is used for moving a enemy from the current map to the adjacent map whenever an enemy moves past the room boundary.  Now enemies aren’t restricted to moving in only one map room.  Similar to the player, I had to add checks to ensure that an enemy doesn’t collide with blocks in the first column or last column of blocks in the right and left map rooms.

One interesting problem is that an enemy would get stuck in a block in an adjacent room whenever it was in the angry state from being shot with the wrong gun.  The problem was that the check for changing the room came before the check to change X velocity (direction) on a collision.  Moving the room boundary checking below the block collision call fixed the problem.


October 8, 2012

Each collectible adds 50 to the player’s money.

Collectibles are very similar to enemies.  An array of collectibles are assigned to each room.  Each collectible has an x,y position and a height and width.  Also, each collectible has an animation frame, which I have set to loop from 0 to 30.  I created a simple collectible model in Blender, which rotates in 30 frames.  Actually, it rotates half way every 30 frames, but it should not be noticeable since the collectible is symmetric on the Y-axis (at least I tried to make it that way).  What makes a collectible different is that projectiles don’t collide with collectibles, and collectibles have a value that gets assigned to the player when the player collides with the collectible.  Unlike an enemy, the collectible “dies” when the player collides with it.  For now, my simple collectible will add money to the player when acquired, but my collectible can be extended later to produce various types of effects.

Handling collision detection for collectibles was also very similar to handling collision for enemies.  I created a method in the Player class which takes the room collectibles as a parameter.  It loops through all the collectibles, and if the player collides with one then it adds 50 money (I’m calling FLOPS) and sets the collectibles “alive” flag to false.  I made one change in the structure for a collectible, where the location and size are contained in a Rectangle object.  For enemies I used two Vector2 objects for position and size.  The major difference is that the Rectangle uses all int values and the Vector2 uses floats.  The int values makes coding a little easier, since the floats have to be casted to int values for storing those values in a Rectangle object for calculating a collision.  I could write my own collision method using floats, but the Rectangle “Intersects” method seems to do the job well.  Finally, I had the World call update on all collectibles in the current room and two adjacent rooms, so that the animation frame value increments for each frame.

Saving and Loading Maps

October 7, 2012

The level editor now allows a map to be saved and loaded.

Began pulling the code out of Resistor for saving game files for my ResistorKit library.  Saving files is much more trickier than just opening up a file handle and writing out a string.  This was probably the most time consuming task in Resistor that produced the smallest results.

The three file IO methods I’ve included in the ResistorKit are beginLoadGame, saveGame, loadGame, and getLoadData.  The beginLoadGame method should probably be renamed, since it just does the processing necessary to get a storage device.  This method must be called and complete before the other two methods are used.  The saveGame method takes three parameters, which are the container name, file name, and data string.  The container name is basically just a folder created in C:\Users\<username>\Documents\SavedGames on Windows.  On the XBox, this is the name of the save on your storage device.  The file name is the name of the file to write out in that folder on Windows.  On the XBox, the user should never actually be able to see the file name.  The loadGame method takes two parameters, which are the container and filename.  After the loadGame method is finished, the character string data from the file can be obtained by calling getLoadData.

In my Level Editor screen, I have assigned beginLoad game to the X button, saveGame to the left bumper, and loadGame/getLoadData to the right bumper.  When the data is saved, it writes out the array of 1’s and 0’s to the text file.  I wrote a method to serialize the data from the array to make this task simpler.  When the data is loaded, the text data is stored in a variable which is displayed to the screen.  Conversely, I wrote a deserialize method which takes the loaded text data and populates the map array.

I’ve also decided to keep one save file for all players.  Saving for a specific profile caused problems with Resistor, so I’ve learned that making one global save file is the much easier approach.

%d bloggers like this: