Blocks

Cleaning Up

Before adding block tiles to the game engine, I pulled out all of the player variables from the GameScreen class and put those in its own Player class.  I also created a Projectiles class to hold the set of projectiles.

Blocks and Collision

For now, I created a simple 12×20 array to represent the blocks on the screen.  This just represents one screen, so later on multiple screens will need to be pieced together to form a seamless scrolling game world.  On each GameScreen update, I pass an array containing the current blocks on the screen to the player.  The player then uses that array in its update method to determine if it has collided with any of the blocks during a fall or a move.  My block collision method does a simple loop through all of the blocks on the current screen, and returns true if the player has collided with any of the blocks.  However, I also add the player’s X velocity and Y velocity to the collision rectangle’s position.  If I wait until after the player has moved into the block to do the check, then the player will become stuck in the block.  That’s why I have to check the collision based on the player’s next position.

If the player’s falling boolean is set to true and they collide with a block, then the falling boolean is set to false.  If the player’s X velocity is non-zero (they’re walking) and collide with a block, then I prevent the player from moving in the X direction.  I could set the X velocity to zero, but that would stop the run animation and the player would have to press the directional button again in the case the blocks move (such as an elevator).  If the player holds down in a direction, they should start moving again as soon as the obstacle is moved.

Walking on Air

One last problem is that when the player walks off of a block, they will continue to float until they jump.  Therefore, I had to add another check if the player is not falling and not jumping, then check to see if they collide with a block if falling downward.  If the player doesn’t collide with a block, then set the falling boolean to true so that the player starts falling.  This condition only arises if the player is not falling and not jumping (they are walking or standing).  Checking this way will be beneficial if disappearing blocks are added, then the player will start falling.  Handling elevators may be a little more tricky, since those are not aligned directly on the tile grid.

Run and Jump

http://www.youtube.com/watch?v=Dc3PoVTmc5U

Jump

It’s been over a decade since I’ve written a side scrolling platformer.  However, it’s sort of like riding a bicycle.  One you’ve did it once, you’ll never forget.

On the surface, it seems really simple.  When the player presses”A” the character starts jumping until the player releases the “A” button.  That’s a starting point, but that allows the player to hold down  the button forever, which results in the character blasting off into space.

Therefore, you’ve got to add a counter to keep track of how long the player has jumped.  If this value reaches a certain point, then the player should start to fall.  This is easily handled by adding a boolean jump variable.  Press “A”, and then the jump boolean gets set to true.  Release “A”, then the jump boolean gets set to false.  If the player reaches the jump limit, then set the jump boolean to false.  In the update function, subtract from the player’s Y position the jump velocity if the jump boolean is set to true.  If the player is not standing on anything, then add the falling rate the player’s Y position.  Starting out, I just used Y == 400 as the ground.  More complex collision detection will be handled later.

This works okay, but it still allows the player to press “A” again while the character is falling, which results in a double jump.  Further, the player can keep jumping over and over again to go as high as they want.  Therefore, another boolean is introduced to keep track of falling.  When the jump period is over, the falling boolean gets set to true, and the player is not allowed to jump again until they have collided with the ground.  At that point, the falling boolean gets set to false.

 

Run Animation

For the run animation, I used Blender to render 3 frames of a new stick man model that I created.  For this model I used additional smoothing before creating the bones.  Then I used Gimp to crop all three images to the same size (128×128).  Then I flipped all three images to create the player facing the opposite direction.  (There may be a function in XNA to do that).

A new integer variable is created to keep track of the current walk animation frame.  In the update method, this variable is incremented.  However, if it changes one image per frame, then the walk animation will go too fast.  This would probably work if you have a graphic for each frame.  However, I only have three for now, so I just divide the animation counter (which maxes out at 30 and gets reset back to 0) by 10.  This provides 3 frames for every half second, assuming that the update function is getting called 60 times a second.

Facing

Shooting seems fairly simple as well, but there is actually a little more involved than one would think.  Just pressing either shoot button will set the pellet to active, but it doesn’t know which way to travel.  Therefore, a new variable has to be added to the player to keep track of which way they are facing.  I used -1 for facing left and +1 for facing right.  That way, I set the velocity of the pellet to the pellet speed times the facing value.  Additionally, the alive value has to be set to false once the pellet reaches the left or right window bounds.

Also, the player can repeatedly press the shoot button, which will keep reinitializing the pellet back to the player’s location.  To avoid this, a check must be preformed to ensure that a new pellet is not taking the place of an already existing pellet.

My First Framework: ResistorKit

Since much of the code to handle screens and gamepad will be the same for Binary Blaster, I decided to write my first game library.  For now, I’m calling it ResistorKit since it borrows a lot of code from the Resistor game.

 

For now, it just includes two classes:  Screen and GamePadHandler.  The Screen class defines a standard format for a game screen, along with handling standard user input events.  The Gamepad class handles the button presses from the active GamePad.

How to Use it

Right click your project in the Solution Explorer (right pane), select Add ReferenceBrowse, and then select ResistorKit.lib.  Under References you should now see ResistorKit.

In your main game class, add the following line to use the ResistorKit API:

using ResistorKit;

Note:  If the ResistorKit.dll library is updated, then you will need to delete the DLL out of the XBox360/bin directory to import a new copy of the library.  Otherwise, it will keep using the old library.

Create GamePadHandler and Screen objects as instance variables in your main game class.  In the update method, call handleGamePad on the GamePadHandler object and pass in the gameTime and Screen object.  Subclass the Screen class, implementing all of the abstract methods.  These methods will be called when a button is pressed/released, on update, and on draw.

In the main game class Draw method, add a call to drawScreen on the Screen object and pass in the spriteBatch, a texture array, a font array, and title safe Rectangle.  Make sure to call spriteBatch Begin and End before and after this method.

That’s all there is to it.  Put the logic to handle button presses in the appropriate methods in the implemented Screen class.  Put the drawing code in the draw method of the screen class.  Put any update logic in the update method.  Multiple screens can be defined, and screens can be switched by assigning the active screen to the current screen instance variable in the main game class.

Using this framework, I was able to get a simple sprite moving, jumping, and shooting around the screen.