Ok, this week we are going to reorganise the internal structure of the game using polymorphism and methods. Until now we had a list of Fish
objects and a list of Crack
objects. Our code become easier when we merge them into one list of GameObjects. After that we make our loop()
much more readable and wqe update the logic in a way that we can easily expand the game. A last topic (a bit more advanced) is adding a friend for Chilly as a second player.
Check the old classdiagram (on top) and the new classdiasgram that we want (below). It looks much less complicated! Do the following steps to arrange this:
Now it’s up to you to implement this diagram into your project:
Player player
, ArrayList<Crack> cracks
and ArrayList<Fish> fishes
and replace them with only one variable: ArrayList<GameObject> gameObjects
.Also adds (other then the diagram suggested) a reference to the Player object (Player player
) as instance variable. The player will be in the list GameObjects, but besides that there is also a direct reference to the player that we can use in the keyboard handling method.
init()
method so that it creates the ArrayList and the player object and adds that to the list.
public void init() {
gameObjects = new ArrayList<GameObject>();
player = new Player(SCREEN_WIDTH/2,SCREEN_HEIGHT/2);
gameObjects.add(player);
}
Player
and add the following to the class GameObject
public boolean collidesWith(GameObject gameObject) {
if (gameObject != this) {
return this.getBoundingbox().intersects(gameObject.getBoundingbox());
}
return false;
}
To keep the code more readable we will split up the loop()
method in several smaller methods. There is not much new code, but a lot of code will be moved. Maybe you sometimes wonder why we’ve setup the methods the way we do. Please note that is all for readability and to make it as easy as possible to expand the game.
Our suggestion is to have the following:
void drawHealthBar(Player player, int y)
which draws the healthbar for the given player at the given y position.void drawGameObjects()
which draws all the gameobjects.GameObject detectCollision(Player player)
which detect wether or not the given player object collides with something. If the player collides to something it returns that gameObject, otherwise it returns zero. Please note this method only returns 1 gameobject at a time, so you can check one collision at a time.void handleCollision(Playewr player, GameObject gameObject)
which handles a collision. In this method you first check if you collide into a Fish
or a Crack
and then do the correct action on the given player.void handlePlayerMovement(Player player)
which handles the movement of the player (only needed if you implemented the advanced movement. This methods does the automatic moving of the player each loop).boolean handlePlayerHealth() {
which handles the player health (The increasing at each interval). It updates the interval and returns true if the health became zero, false if not.boolean spawnCracksOrFishes()
which spawns a crack or fish if needed. It increments the timers and when a timer ends it places a fish.In our code the loop methods now looks like this, which is much more clear then before and offers oppertunities for easy extension of the game:
public void loop() {
// Clear the screen and add the background
SaxionApp.clear();
SaxionApp.drawImage("resources/background.png", 0,0, 1024,768);
//Draw the health bar and gameObjects
drawHealthBar(player, 20);
drawGameObjects();
//Handle player movement and health
handlePlayerMovement(player);
if (handlePlayerHealth()) {
SaxionApp.quit();
}
//Spawn crack or fishes and check collisions
spawnCracksOrFishes();
GameObject gameObject = detectCollision(player);
if (gameObject != null) {
handleCollision(player, gameObject);
}
}
SO, now we have made the code more generic it becomes a lot easier to extend the game with more gameobjects. It is even quite easy to add a second player. It’s up to you how to do that, but here are a few clues:
Player
and add it to the list of GameObject
’s.void loop()
method and add calls for player 2. It should be quite easy.void keyboardEvent(KeyboardEvent keyboardEvent)
to add keys for player 2, for example WSAD.void handlePlauyerHealth()
method so that it also checks the health of player2. If one of them dies, end the game. Or even better: Show a message who won and restart the game (a bit harder to do).