Game Pause Screen Code Implementation Sprint Two - UQdeco2800/2022-studio-2 GitHub Wiki

Introduction

Author: @Rey-666

Pause/Resume game function is a newly added feature for sprint two, the reason why this feature should be included in this game is because game pausing is one of the most fundamental features across game history. More importantly, a great once said, "Game pausing feature makes a single-player game dope." What is more, game pausing makes the game more coherent to play. For example, if the player is using the crafting table and the game is not paused, the player will easily get killed by enemies. That said, implementing the feature requires a great understanding of the logic behind the code.

General Pausing/Resuming

The first step is to implement a fundamental pause game function, the purpose is to allow the player to use "ESCAPE" key to controll the game pause/resume.

First, I bind the key "ESCAPE" to trigger the pausing event in the KeyboardPlayerInputComponent class. Once the key is pressed, it will then activate the event listener, and send out a message with "game paused". This message can be then treated as a global variable which will let the related functions know that player has already pressed the "ESCAPE" key, waiting to reponse...

However, the challenge i ran into is how to let player pause and resume the game with the same key, and the solution i have come up with is to use a keyPressedCounter variable to keep record of the number of times player has pressed the button, the game will be paused only on the even number of presses. (variable is initialized to 1 at the begining). Another benefit of this code block is that it will deal with pausing/resuming when the user is interacting with the crafting table. This is done by setting an boolean varable within the OpenCraftingComponent class to retrive the crafting table status, the keyPressedCounter will only be increment when crafting table is closed. Another advantage is that, this will prevent messing up pausing logic when player is crafting.

case Keys.ESCAPE:
        if (!OpenCraftingComponent.getCraftingStatus()) {
          keyPressedCounter++;
        }
        if (keyPressedCounter % 2 == 0) {
          entity.getEvents().trigger("game paused");
          return true;
        }

After the trigger message has been sent out, the game engine will then look for the "person" who is responsible for this pausing event. Therefore, in correspondence to this, the OpenPauseComponent is then introduced. The underlying logic of this class is to treat pausing ability as an entity, if only the entity is created, it can then have the power to listen to an event and responde to that.

As for to actually pausing the game, it is done within the EntityService class. Specifically, the update() method, this method is responsible for constantly updating the game frames. Pausing game is done by creating a setter method to manipulate the pause status boolean variable. For instance, when game paused is listened, set pause to True, and vice versa.

More importantly, in order for game consistency, the game will automatically paused when the player is interacting with the environment. At this stage when the player is interacting with crafting table.

public void create() {

        logger = LoggerFactory.getLogger(OpenPauseComponent.class);

        entity.getEvents().addListener("game paused", this::openPauseMenu);
        entity.getEvents().addListener("game resumed", this::closePauseMenu);
    }

private void openPauseMenu() {
        if (isOpen == false && OpenCraftingComponent.craftingStatus == false) {
            ServiceLocator.getPauseMenuArea().setPauseMenu();
            isOpen = true;
            EntityService.pauseGame();
        }
    }
private void closePauseMenu() {
        if (isOpen == true) {
            ServiceLocator.getPauseMenuArea().disposePauseMenu();
            isOpen = false;
            EntityService.pauseAndResume();
        }
    }

Last but not least, in order to make the game fun to play, we decided to display a pausing menu when the player paused the game. Although the player cannot actually interact with the pausing menu for this sprint, the menu has unquestionably made the game more attractive.

The below code block is resposible for displaying the pause menu asset onto the game screen. First, since java is an object oriented language, I created the assest as an image object:

public void setPauseMenu() {
    pauseMenu = new Image(new Texture(Gdx.files.internal
            ("images/Crafting-assets-sprint1/screens/pauseScreen.png")));

After the object is created, I can then set the position of the pause menu to be at the center of the screen, this also requires the game engine's GDX graphics functions:

    pauseMenu.setPosition(Gdx.graphics.getWidth()/2 - pauseMenu.getWidth()/2,
            Gdx.graphics.getHeight()/2 - pauseMenu.getHeight()/2);

What's more, I then initialized an pausingGroup node for adding actors on 2D scene graph, pauseMenu is now added as an actor to use the draw() method to finally displays it on the game map.

    pausingGroup.addActor(pauseMenu);
    stage.addActor(pausingGroup);
    stage.draw();

Lastly, the setPauseMenu() method can then be accessed within the OpenPauseComponent class to be triggered with the pausing/resume event at the same time.

Some code implementations inspired by @lyphng

More information/javadoc go to crafting branch, under crafting package.