Home > Web Front-end > JS Tutorial > Space Defender - part Game States

Space Defender - part Game States

WBOY
Release: 2024-07-21 08:36:48
Original
683 people have browsed it

In the previous post we've made use of the HUD and now our game is basically done, but it's missing a few things. We need to add a game over screen with a way to restart the game. We also want to add a screen when you just started the game, instead of just starting the game right away.

Game States

We're going to add a few game states to our game. We're going to have a gameState enum that will hold the different states of the game. We'll also have a variable that holds the current state of the game.

Add the following code right at the beginning of your main.ts file:

enum gameStates {
    "PLAYING",
    "PAUSED",
    "GAME_OVER"
}
let gameState = gameStates.PAUSED;
Copy after login

This code creates an enum called gameStates that holds the different states of the game. We then create a variable called gameState that holds the current state of the game. We set the initial state to PAUSED.

Before we do anything with these states, we need a reset function. This function will be called right before we start the game. Add the following code to the bottom of your main.ts file:

function resetGame() {
    lives = 3;
    level = 1;
    score = 0;
    setHudValue("gameLives", lives);
    setHudValue("gameLevel", level);
    setHudValue("gameScore", score);
    Player.x = app.screen.width / 2 - Player.width / 2;
    Player.y = app.screen.height - 50;
    bullets.forEach(bullet => app.stage.removeChild(bullet));
    enemies.forEach(enemy => app.stage.removeChild(enemy));
    bullets.length = 0;
    enemies.length = 0;
    setEnemySpawnInterval();
    spawnEnemy();
}
Copy after login

This will set all the values to their initial starting values, clear the bullets and enemies from the stage and the arrays, reset the player's position, and set the enemy spawn interval. Then start the game by spawning an enemy.

Now that that's set, let's add a way to start the game.

Starting the game

We're going to add a new KeyHandler for that. Add the following code right after where we defined the KeyHandler for the left and right arrow keys:

KeyHandler(
    "Enter",
    () => {
        if(gameState !== gameStates.PLAYING) {
            if(gameState === gameStates.GAME_OVER) {
                resetGame();
            }
            gameState = gameStates.PLAYING;
            togglePauseText();
        }
    }
);
Copy after login

This code will start the game when the player presses the Enter key. If the game is not in the PLAYING state, it will set the game state to PLAYING. If the game is in the GAME_OVER state, it will reset the game and then set the game state to PLAYING.

But the player wouldn't know this, so we need some text to tell the player what to do. Add the following code right after where we defined the KeyHandlers

// A simple text style, 24px white text
const textsStyle = {
    fontSize: 24,
    fill: 0xFFFFFF
};

let startGameText = new PIXI.Text({
    text: 'Press enter to start the game',
    style: textsStyle
});

startGameText.y = 250;

function togglePauseText() {
    if(gameState === gameStates.PAUSED || gameState === gameStates.GAME_OVER) {
        // Since the text can change, we need to reposition it.
        startGameText.x = app.screen.width / 2 - startGameText.width / 2;
        app.stage.addChild(startGameText);
    } else {
        app.stage.removeChild(startGameText);
    }
}
togglePauseText();
Copy after login

This code creates a new text object that says "Press enter to start the game" and positions it in the middle of the screen. It then creates a function called togglePauseText that will show or hide the text based on the current game state. It then calls this function to show the text when the game is paused or over.

Now, we would also like to pause the game.

Pausing the game

Add the following code right after where we defined the KeyHandler for the left and right arrow keys:

KeyHandler(
    "Escape",
    () => {
        if(gameState !== gameStates.PAUSED) {
            gameState = gameStates.PAUSED;
            startGameText.text = 'Press enter to resume the game';
            togglePauseText();
        }
    }
);
Copy after login

In this code we'll set the gameState to PAUSED when the player presses the Escape key. We'll also reuse the startGameText object and set the text to "Press enter to resume the game".

Using the game states

Great, now that we can toggle between PLAYING and PAUSED states, let's actually use these states, and have the game act accordingly.

If we're not in the PLAYING state, we don't want to set the playerSpeed when the player presses the left or right arrow keys. Add the following code into the KeyHandlers where we set the playerSpeedX to 500 or -500 for the left and right arrow keys:

if (gameState !== gameStates.PLAYING) {
    return;
}
Copy after login

Also add the above code into the handler for the spacebar KeyHandler, so that the player can't shoot when the game is paused or over.

Next, update the if statement in the spawnEnemy function to look like this:

if(!document.hasFocus() || gameState !== gameStates.PLAYING) {
    return;
}
Copy after login

And finally, the whole game loop doesn't need to fire if we're paused, add the following code right at the beginning of the game loop:

if(gameState !== gameStates.PLAYING) {
    return;
}
Copy after login

Game Over

Now that we have a way to start and pause the game, let's add a game over screen.

Where now we have a console.log("Game Over"), we want to set the game state to GAME_OVER and show a game over text. Replace the console.log with the following code:

gameState = gameStates.GAME_OVER;
startGameText.text = 'Press enter to restart the game';
scoreText.text = `Score: ${score}`;
scoreText.x = app.screen.width / 2 - scoreText.width / 2;
app.stage.addChild(gameOverText);
togglePauseText();
app.stage.addChild(scoreText);
Copy after login

This code is using two more text objects that we haven't created that yet, lets do that.

Right after where we created the startGameText object, add the following code:

let gameOverText = new PIXI.Text({
    text: 'GAME OVER',
    style: textsStyle
});

gameOverText.x = app.screen.width / 2 - gameOverText.width / 2;
gameOverText.y = 200;

let scoreText = new PIXI.Text({
    text: 'Score: 0',
    style: textsStyle
});

scoreText.y = 300;
Copy after login

Now, we should be able to play the game, pause it, and restart it when we lose.

Conclusion

And that's it! You can now play the game, pause it, and restart it when you lose.

I am aware that this last part might have been a bit overwhelming, but I hope you managed to follow along and understand everything, don't forget you can always check out the full source code. If you have any questions or feedback, feel free to reach out to me on X or leave a comment below


And this is the final part of this small series, I hope you enjoyed it and learned something new. A small thing I'd like to point out while leaving you with this, is that this is a very basic game, and there are many ways to improve it. You could add more enemies, power-ups, different levels, and so on. I encourage you to experiment and try new things, that's how you learn and grow as a developer.

Also, the way this game is structured is not the best way to structure a game, but for the purpose of this tutorial, I wanted to keep it simple and in one file. In a future tutorial, I might show you how to structure a game in a more scalable way.

Thank you for reading all the way through this tutorial!



Don't forget to sign up to my newsletter to be the first to know about tutorials similar to these.

The above is the detailed content of Space Defender - part Game States. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template