I’m repurposing project 1 for this game – rather than starting from scratch and reusing elements I’m editing the existing code – which is never a good idea; but one I find hard to resist.
I wasn’t completely happy with the game structure with project 1 & wanted to take a stab at reviewing and updating – Hopefully improve things a little. The new version isn’t perfect, but I think it’s an improvement.
It’s based almost entirely on using enums to define ‘states’, managers to switch between states (e.g. GameStateManager & GamePlayManager) & elements which implement different code/functionality depending on the current state.
I’ve outlined each class/element in a bit more details below;
GameStateManager: As with Project 1 (Block Runner) – The game state manager looks after the top level game state – That is, are we on the title screen, highscore screen, playing the game, etc… Top level GSM stuff. It’s still overloaded; but I’ve begun simplified things a little – Game Over is now managed by GamePlayManager (though at the end of a game the GameStareManager still checks to see if the player has a new highscore).
GamePlayManager: Looks after the game state ‘in-game‘ – It’s concerned with things like; initializing the level, displaying the level intro message, playing the game, displaying end of level messages & handling gameover, etc.
Player: Modified from Project 1‘s player class – This is looks after the current state of the player – Are they entering the level, or exiting, playing the game or have they fallen off a tile? It also managers the player input and updates player input accordingly.
A notable aspect is the way player deaths are handled – Once a player is killed, the Player class looks through all the current tiles on screen and identifies all safe/standard tile types (only checking against the top half of the screen) – It then randomly chooses one to be used as the spawn point for the player re-entering the level. If there are no safe tiles currently active, the level will continue to scroll until a safe tile becomes available.
TileManager: Based on the ‘PlatformManager‘ class from Project 1 – Unlike the classes above, this isn’t managed by state/enum.
Each level is made up of tiles – Tiles create the path the player must travel through in order to reach the end of the level. It’s the environment the player exists in while playing the game – The meat of the game.
There are lots of different types of tiles used in the game – e.g. normal/standard tiles act like platforms in a standard platform game – players can safely bounce onto/off-from them as often as they like – Arrow tiles allow the player to bounce twice as far (avoiding obstacles or large gaps in the level), walls block the players path, lava tiles kill the player on collision etc…
The TileManager class manages these tiles – Instantiating, positioning, scrolling and ultimatly destroying tiles.
For the tiles themselves, I’ve followed the example given in the Space Shooter demo code – Each tile type is defined as a prefab; these are plugged into the TileManager class as generic GameObjects – This allows me to easily manage the tile types with the TileManager class, whilst allowing each tile to maintain it’s own personality.
At the start of each level, the TileManager class loads a (text) map of that level. It uses this map to populates a two-dimensional array of GameObjects (Tiles) – This builds the level.
Since levels can be pretty large, so I don’t want to have ALL the tiles instantiated & active at one time – It’ll soak up far too much memory. So the array only holds the tiles which are onscreen at that time (with a little offscreen buffering to smooth things out).
Each loop TileManager updates the position of each tile in the array – scrolling them down the screen – Once a row has moved off the bottom of the screen; TileManager reads the next line from the level map; populates the offscreen row with the new tiles & repositions them at the top of the screen, ready to scroll down and confound the player.
Scoreboard: Currently still fairly undefined – The relevant fields are in place (score, hiscore, lives, jumps) – & I’ve started hooking them up to the game code – But I’m not particularly happy with the way it currently looks in game – So I’m intending to finish connecting to the game data (hiscores are proving a pain) – But then leaving all the heavy lifting (animations, transitions, etc) – Until I decide how I want it to actually work.
There’s a couple of important areas still undefined; the background & enemies.
Background: On the C64 version of the game the background seems to be created out of tiles (as with the top layer) with generic grass, mud, water type images – Using parallax scrolling to give the impression of depth.
Enemies: From what I can gather enemies in the original bounder are made up of two classes/types;
Type 1. Enemies which operate in the expected manner – moving around the screen, needing to be avoided by the player.
Type 2. Enemies which sit on tiles, acting either as one-touch kill obstacles – or in a more esoteric manner e.g. warp enemies, which, upon collision, transport the player to another (safe) part of the screen.
With my current setup, I’m more inclined to class type 2 enemies as tile types.
Though I’m intending to wait until I’ve setup a wider range of tiles before I consider this further.
A short video demonstrating the current framework…
For now that’s it.
For my next step I’m intending to start defining & adding tile types to the game – getting their functionality defined & making them look a little more interesting/unique.
So, first I need to figure out what different tile types there are & how they operate.
Below is a quick video demonstrating how things are at the moment
Next post: 2.3 Palette Swap
Last post: 2.1 Introduction