Radiant Socket

http://www.youtube.com/watch?v=2qUl7osMM60

The Radiant socket allows the player to see more in a dark room.

Tonight, I started working on the first helmet socket, which is the Radiant socket.  This socket will allow the player to see in dark rooms.  In dark rooms with no sockets, the player will only be able to see their character.  With Radiant +1, the player can see enough to move around effectively, but it will still be difficult to see enemies.  Enemies can be seen from a distance with Radiant +2.  Almost all of the room can be seen with Radiant +3.

I found a good 2D Fog of War example, which helped me understand how to create the lighting effect.  First of all, I had to create a bitmap that represents the lit area.  This was created in Gimp by using the gradient tool with the radial shape option select.  Clicking on the gradient allowed me to select the color as FG to Transparent, with the FG set to pure white.  I loaded this gradient as a texture in the main class.  A new RenderTarget2D object also has to be created and initialized in the LoadContent method.

 

In order to draw the light gradient, I found that it is necessary to pass the RenderTarget2D and GraphicsDevice to the drawScreen method of the Screen.  Since ResistorKit doesn’t currently handle this, I just created a drawRadiant method in the GameScreen class.  I do a class comparison in the main draw method using the “is” operator to see if the current screen is GameScreen.  If the current Screen is a GameScreen, then it uses the drawRadiant method which takes the RenderTarget2D and GraphicsDevice as parameters, otherwise it uses the regular drawScreen method.  Ideally, I’ll go back and update ResistorKit to overload the drawScreen method to accept the additional parameters.

In the GameScreen class drawRadiant method, I first set the rendering target to the passed in RenderTarget2D.  Then I draw the light gradiant texture, with the BlendState.Additive option enabled.  I created a function in the Player class, which returns how big the radiant area should be, based on which Radiant socket is equipped.  Then it draws the gradient image based on the radiant size returned by the Player class.  I am also careful to draw the light gradient centered on the player based on their screen location.

Next, the render target gets set back to null, and the regular game world screen is drawn.  I extracted the status overlay into another draw method, which includes the health bar, debug information, and money display.  This is because I want those items to always be displayed regardless of radiant light size.

After drawing the game world screen, a BlendState object is created.  The two DestinationBlend properties are set to Blend.SourceColor, and the two SourceBlend properties are set to Blend.Zero.  I don’t fully understand this, but that’s how it is set up in the example and it works.  Now the lighting effect is drawn using another call to SpriteBatch.begin, but this time the BlendState object is passed as a parameter, and the RenderTarget2D object is passed as a parameter to the Draw method.

Finally, I call the SpriteBatch.Begin method again with no parameters and call the Status Overlay drawing method that I created to draw the health bar and debug information.

I also did a little more work on modeling in Blender, by starting on a new player model.  I’m hoping that this one will end up looking a little more realistic.

Updated Weapon Sockets

http://www.youtube.com/watch?v=6AXjbSZAU5I

Demonstration of all sockets thus far, now in HD!

Tonight I updated the ice gun socket, so it now has three levels of magnitude.  Ice +1 will freeze an enemy for 2 seconds, Ice +2 will freeze an enemy for 4 seconds, and Ice +3 will freeze an enemy for 6 seconds.  I’m thinking about expanding the types of Ice sockets.  I could have a Chill socket that just slows the enemy.  Also, I could have a separate Freeze socket which will allow the player to stand on the enemy without being damaged.

The fire gun socket is a new ability I added tonight.  The idea behind the fire gun is to apply burn damage over a period of time.  In order to do this, I had to scrap the two gun system of shooting ones and zeros.  That’s because the burn damage needs to just be a fraction of the actual weapon damage.  The damage over time concept does not work with the one and zero gun concept.  Overall, I felt that most players wouldn’t understand the binary blasting mechanic, and it was going to be problematic to correlate the binary sequence to decimal numbers in the game.  I may end up making the binary blasting concept a bonus mini-game.

The Fire +1 socket will burn the enemy for 5 damage each second for 3 seconds.  The Fire +2 socket does the same except for 6 total seconds, and Fire +3 will last for 9 seconds.  Currently, if an enemy is burning then it is just shaded red.

I also added Long +1, Long +2, and Long +3 sockets which increase the shot distance.  To implement this, I had to add a variable that keeps track of the distance modifier to the projectile Pellet class.  The base lifetime for a pellet is 20 frames, and for each increase in Long magnitude, 5 frames are added to the base lifetime value.  After I get multi-sockets working, I plan on allowing the Long socket to work with the Ice and Fire sockets.  However, I don’t know if I will allow Ice and Fire to be active at the same time.

Floating Socket

Small update tonight to implement three new boot sockets.  These new sockets allow the player to float in the air after reaching the apex of the jump, if the jump button is still held.  The amount of float time is static (20 frames), and that time is doubled for the Float +2 socket and tripled for the Float + 3 socket.

 

As with the “looking up” and “looking down” states, the floating state does not currently have animation sprites.  Therefore, I just have the word “floating” display on the player for testing purposes.

Floating could have been implemented many ways, but I like booleans so I created an isFloating bool to signify if the player is floating.  I also have an integer tracking the amount of float time.  When the player jumps, if a Float socket is equipped then the float time integer gets set to the number of frames that the player should float based on which Float socket is equipped.  When the player’s jump acceleration reaches zero, then the isFloating value gets set to true if the float counter is greater than zero.  Otherwise, the player will start falling.  On each update, the float counter is decremented until it reaches zero.  At that time, the player will start falling as they normally would after reaching the jump apex, and the isFloating bool gets set to false.  The separate bool and integer variables may be slightly redundant, but I think it makes the code more readable.  A future optimization could be to replace the bool variable with a function that returns true if the float time is greater than zero and false otherwise.

I also slightly modified the crouching code.  If the player is walking and rolls the control stick to the down/forward position, then the player will walk and look down.  From this state, if the player rolls the control stick completely down, then the player would still be looking down and standing (not crouching).  This was to prevent the player from crouching when holding down and forward, when the player should be moving.  In ResistorKit, I only have methods that fire when up, down, left, and right are pressed or released, so the crouching code was only fired when the down and pressed action was fired.  The player is not allowed to crouch if the jumping, falling, or walking states are active.  To fix this, in the code that causes the player to stop walking, I added code to set the player to the crouching state if the player is looking down.  This behavior is slightly different from other classic platformer games that also don’t set the player to crouching when rolling from foward to down, but I feel that my new way feels more natural.  With the old way, the only way to crouch was to press directly down from a standing position which feels clunky.

Floating was a fairly simple mechanic to add in about two hours.  I’m hoping to get back to character modeling, but there is a huge learning curve for me to complete that task.