Map Flipping and Tweaking Collision

http://www.youtube.com/watch?v=93qzG6ulogQ

Updated map flipping, fixed offset collision issue, added title safe overlay image.

More Bounds Checking

Noticed that the right bounds wasn’t symmetric with the left bounds.  I had 200 pixels for each bounds, but forgot that I needed to subtract off 48 for the right bounds to account for the player’s width.  This set the right bounds at a location that was not a multiple of 5 (1032 = 1280 – 200 – 48), which caused problems since the player’s walk speed is 5 pixels.  Thefore, when the player’s location and velocity passes the right bounds, then I have to calculate the difference between the bounds and the new location.  I set the player’s location to the right bounds, and add the difference to the level scroll offset.

The flipping between maps was working really well, but I forgot one case which is really noticeable when it happens.  I am only checking for map flips when the player is at either the left or right bounds.  However, it is possible for the player to backtrack and cross the boundary between rooms, when the boundary in the middle of the screen between the two bounds.  However, this is fairly simple to calculate.  If is between the two bounds, and the player’s X position is less than room offset, then flip back to the map on the left.  If the player’s position and the negative offset are greater than the room size, then flip back to the map on the right.

Title Safe Overlay

Found a nice PNG layover on the XBox Creators Club forums which shows the title safe area for a 1280×720 screen, which can just be drawn over the game screen, since the center of the image is transparent.

Collision Offset

Since the player falls at a rate of 5 pixels per update, there is a small problem when the user falls to the ground which may not be noticeable.  Since the tiles are not multiples of 5, then the calculation of the next fall frame may indicate a collision and the player should stop falling.  However, this will cause the player to stop at the multiple of 5, which may be a few pixels above the actual ground.  This is not really noticeable until the hit box is drawn around the player graphic.

This is also a problem when running into blocks, since the player runs at 5 pixels per update.  Turning up the run and jump speed to a higher value (like 20) makes this issue more noticeable.

 

   

To fix this, I went ahead and updated the player’s location to the block boundary in the collision method.  Originally, I just had the collision method return true or false, based on if they have collided with a block.  Updating the player’s location in the collision method probably isn’t the best programming style, but I really didn’t feel like calculating the number of offset pixels, making new variables, and passing out the number of offset pixels to the calling method which is bad style in itself.  Probably the most elegant solution would be to return a Vector (x, y pair) containing the number of offset pixels, or null if the player has not collided with any blocks.

 

The Level that Never Ends

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

In this video, the world is one continuous loop.  Each set of colored blocks represent one “room” in the game world, which are pieced together to form a continuous scrolling world.

Tile Size Change

Scaled down the tiles from 64×64 to 48×48.  This allows 15 rows (previously 11) and 26 columns (previously 20) on the 1280×720 pixel screen at once.

Scrolling

Scrolling isn’t too difficult, but it really makes you think.  First, set two constants which will be your left and right bounds.  If the player walks right and their position is greater than the right bounds, then don’t move the player and scroll the level left.  This can be accomplished by storing an X offset variable.  Then, draw all the tiles using the X offset to shift the screen.  I ended up setting these at 200 for the left bound and 1080 for the right bound, which gives 200 pixels of buffer on both sides of the screen.

Once the offset equals the size of the room minus the right bounds, then it means the player should be moved to the next room.  I created a Level class which keeps track of all of the level’s rooms.  Additionally, each room has a reference to the left and right room.  When moving right to the next room, set the current room to the room to the right, and set the X offset to room size minus the right bounds.  Be careful as well to only check for a right room flip whenever the player is at the right bounds, or a left room flip when the player is at the left bounds.  Otherwise, the player will continually flip rooms, because the offset will be set to a value outside of the bounds at the other end.  I’ll admit, this gave me a bit of a headache getting all of this straight.  However, in the end this will work out much better than having one huge array.  I had to draw out the transitions on paper first to get it straight in my head.

What made this more of a pain was the fact that my screen width (1280) isn’t a multiple of the tile size (48).  Thefore, I only used 26 columns for a room, which left a small difference (32 pixels) between the room size and the screen size.  Remembering when to use the screen size and when to use the room size was quite cumbersome, but in the long run I think this will allow rooms to be created of any size.

Setting the last room’s right room to the first room, and setting the first room’s left room to the last room turns it into a continuous scroller, similar to games like Magic Sword or Odin Sphere.  I’m a big fan of those games, so I’m going to leave it that way for now.

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.