Weapons and Armor

Added new Weapon and Armor classes.  The Weapon class contains an attack value, recoil rate, shot distance, and a List of Sockets.  The Armor class contains a defense value and a List of Sockets.  I have subclassed Armor has for each body location, which are head, hands, body, and feet.  These subclasses currently don’t have any unique properties which may be bad coding style, but I think it is better than having a “type” value in the Armor class.  Plus, it opens the possibility for adding unique characteristics for each armor type.  I also made sure that the instance variables in the Armor class are set to protected so that those are accessible to the subclasses.  The EquippedSockets class has constants for the body parts, but I’m planning to remove the EquippedSockets class once the new Armor system is implemented.  Both the Weapon and Armor classes have an ID variable, which will make it easier for reading and writing save game files.  A cost variable is also included in both Weapon and Armor, which determines how much it costs to buy or sell the item.  The Player class now has a List of Weapons and a List of Armor that the player has acquired.

I also created an EquipmentCatalog class which contains instances of every Weapon and Armor in the game.  When a new weapon or armor is acquired, I’ll probably just clone one of the objects in the Catalog and assign it to the player.  I could have the player’s acquired Weapon and Armor Lists point to references in the Catalog, but that won’t allow the equipment to have unique properties like a Socket list.  I may also want to add a durability value that would be unique to an item instance, which decreases the cost value of the weapon.  Also included in the EquipmentCatalog class is a method to return random Weapons and Armor.  In the future, I’ll probably add parameters so that a random item can be generated within a specified level range for enemy drops.

Currently, I’m using the SI metric prefixes for the names of the weapons and armor.  I’m not that creative, and these names may actually teach the player something educational.  To keep things simple, I’m going to display item properties graphically as bars (or something similar) instead of raw integers.  Therefore, the first weapon will have one bar for attack, recoil rate, and distance.  The next weapon will have two bars for attack.  I may mix up some of the weapon statistics so that each excels in one of the three statistics.  There may also be a bonus for equipping all weapons and armor in the same level series.

While the weapon’s first name will determine the level and attack value, the weapon’s second name will describe the other attributes.  For instance, “Blaster” will be a balanced weapon, “Zapper” will have a higher recoil rate but lower distance, and “Ray” will have low recoil rate and high shot distance.

I also extracted out the socket information into its own class.  Previously, all of the socket information was contained in the EquippedSockets class, but that only allowed one socket to be equipped to each body part.  For the Weapon and Armor classes, I added a variable that tracks the maximum number of sockets that can be equipped on that equipment, and the actual Socket instances are kept in a List for each piece of equipment.  The new Socket class only contains the socket ID, name, and type (body location).

The Collectible class has also be subclassed with CollectibleWeapon and CollectibleArmor classes.  These classes serve the same purpose as Collectible, which is a collectible item on the game screen.  However, the subclass contains one additional instance variable which is a Weapon or Armor object.  When the player collides with the collectible, that item will be added to the player’s weapon or armor List.

Modified the enemy death code, so that a new Collectible is instantiated at the location of the enemy.  The enemy calls the dropItem method on the room object, which takes the drop location as parameters.  The dropItem method uses the random methods in the catalog to get a reference to a random item, which is assigned to the collectible.  Then it adds that collectible to the room’s collectible list.  In the future, I would like to have the defeated enemy determine which item is dropped.  One decision I had to make is the location of the EquipmentCatalog.  The room does not have any references to anything outside of itself, however it needs a reference to the EquipmentCatalog to assign to the Collectible that the enemy drops.  I am now creating a new instance of EquipmentCatalog in the dropItem method, but that will very wasteful of memory since it will need to be cleaned up every time an item is dropped.  I will have to think about this some more.  The EquipmentCatalog may need to be a static class, but I currently have all of the Weapons and Armor defined in dynamic Lists in the Catalog constructor, which may not be allowed in a static class.  I haven’t created graphics for weapon and armor drops yet, so I’m using the standard money drop shaded green for weapons and blue for armor.  The name of the item appears above the collectible on the game screen.  On the equipment screen, the list of all acquired weapons and armor are displayed.  However, I have not implemented the ability to equip those items yet.

Aside from the equipment changes, I added a boolean in the room class that determines if the lights are on in the room.  Only rooms with this value are drawn dark with the radiant value.  There is a slight glitch here, because once the player crosses the screen boundary the whole screen turns dark (including the portion of the previous room that was lit).  I will need to resolve this later to give it a gradual transition from light to dark.

New Attract Screens

I used Blender to render three models for the attract screens.  I decided to drop the first screen, so there are three total screens which display for 5 seconds each before the title screen is displayed.

I used my existing image of the B.A.N.G. logo as a guide to create the first model.  I rotated the camera slightly on the Z axis to give it more of a 3D appearance.  Then I rendered the image and exported it to a PNG file.  Eventually, I plan to use the actual model in the game.  I created a new background image in Gimp, using Script-Fu Lava as the background.  Using Colorize and Brightness-Contrast, I made the background image a light green color.  Then I pasted the rendered model image into a new layer, and entered the text on another layer.  Creating the raised text effect is sort of a pain.  First I entered the text in black.  Then I used the color chooser to select the text, and then I copy and paste the selection into a new layer.  With the new text still selected in the new layer, I fill the selection with the  light green color.  Finally, I slightly move the new text selection up and to the left 2 pixels.  I may end up rendering the text in real time using the ResistorKit drawRaisedString method, but it’s much easier to place the text in Gimp than placing it programmatically.

 

For the mass-to-binary converter screen, I just used a cylinder and extruded two wider cylinders on the top and bottom.  Also, I removed all the vertices in the inner cylinder to give it an open appearance.  I also placed a light green light source in the inner cylinder.

 

For the final digital world screen, I am just using a Blender ico-sphere with a texture mapped to it.  The texture is a bunch of 1’s and 0’s on a green background.  The wrapping didn’t turn out exactly right, so that’s something I will probably want to fix later.

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.