I have finished many of the core mechanics of my Android side-scroller which I have decided to call Bob’s Race through Space. In the two weeks since the beginning of class I have built the physics system for in-game objects, programmed both on-screen controls and physical gamepad input, made one simple enemy which can hurt the player or be squished by the player jumping on it, and started working on stats like health, coins collected, etc.
Bob’s Race through Space is an idea that I’ve had for a while now but never finished. I actually did start it at one point and got some of physics and controls finished. After looking through the code, I decided it was messy and not very well organized. Using my original code as reference, I started a whole new Android Studio project and started rewriting the game.
When I talk about the physics system, I’m referring to gravity, ground detection, wall detection, and detection of other solid objects. In the game, there are objects (the player, crates, etc.) that must fall due to gravity and stop when they hit the ground. If they are moving horizontally, they must also stop when they hit a wall or another solid object. Objects may even be able to push each other (the player can push stacks of crates).
For detection of the ground and walls, I decided to use what I usually call a “collision map” but is sometimes referred to as a “bitmask”. This method uses two images to create the layout of the level. One image is what the player actually sees. It is decorated, detailed, and you can see all the platforms on it. However, detection of the platforms from this image would be difficult because they are too complicated! There many different colors, decorations, how would we know what part is solid, what isn’t? The image below is the test level that I created. You’ll be able to compare the complexity of this image to the collision map soon.
The second image as you may have guessed is what I call the collision map. It is the same dimensions of the previous image, but looks much different. In the collision map, the sky is black, solid platforms and walls are white, and “semi-solid” platforms are cyan.
The position of a physics compliant object can be compared to this image to determine if it should be falling (in the black) or stopping (in the white or cyan). Objects cannot jump through the white portions of the map. If an object is moving upwards (like if the player jumps) and the top of the object hits a white portion, it will stop moving upwards and begin falling down. The cyan portions however can be jumped through and landed on top of. The player can also press the down button to fall through these portions of the map.
Physics compliant objects can also stack on top of each other and push each other around. In the image below, you can see the player standing on top of some crates that are stacked on each other. I’ll use this in the game for puzzles that require the player to push crates and stand on top of them to get to places.
The physics system is the most complex part of this project so far. Luckily I had some previous work of mine to work off of but it was still difficult and time consuming. I spent a lot of time fixing glitches and it seemed that every time I fixed one it created another. Collision detection with the map wasn’t too bad, but collision detection between objects was difficult. I ended up with a pretty good physics system that will do everything I need it to, but I think if I were to do it again I would implement a more accurate third party solution like Box2D instead of trying to make my own.
Bob’s Race through Space includes four basic controls: left, right, down, and up. In the previous image, you can see the on-screen buttons for these controls labeled with arrows. A Bluetooth controller can also be used to play the game. Using a Bluetooth gamepad will even hide the on-screen buttons. I used an InputListener class to handle input from both the on-screen controls and the physical controller. Both types of controls fire the same events in the InputListener class so that both types of controls have the exact same effect in the game.
The controls fire methods in the player class that cause the player to do the corresponding action. For example, there is walkLeft() and walkRight(). All of these methods modify variables in the player’s physics data component. For walking left and right there is a target X velocity variable. The physics system will accelerate the player until it is moving at the target X velocity. This way, there is a small amount of friction. The amount of friction could be adjusted for things like ice platforms.
Pressing up (or A or B on a Bluetooth gamepad) will change the player’s Y velocity so that it will jump up into the air. The amount of time the button is held will affect how high the player jumps. Pressing down while on a semi-solid platform will cause the player to fall through the platform. This is done by telling the physics system to temporarily ignore cyan colored platforms.
Enemies and Level State
Each level in the game will have a certain number of enemies remaining, a certain number of collectible tokens (stars, coins… I haven’t decided what yet), a timer, and of course the player’s health. I have a “Level State” class that will track all of these things. The health portion has been implemented and is used to display the correct number of hearts as you can see in the last image.
In the next image you can see a basic enemy. This enemy bounces back and forth between the walls in the map. If it touches the player, the screen will flash red, a heart will be lost, and the player will blink for 3 seconds indicating that it cannot be hurt again until the blinking stops. If the player jumps on the enemy, the player will bounce off and the enemy will be destroyed, falling through the map and off the screen.
I have finished most of the core mechanics for the game and so I am on schedule. Over the next week I will work on programming UI related things like the start menu and level selection menu. If I have time, I may work on a Game Over screen as well. The start screen needs include the title, a “play” button that brings the user to the level selection screen, an “options” that will be used later for volume controls and on-screen control adjustment, and possibly some other buttons for future purposes.