Table of Contents
PixiJS Setup with Vite and TypeScript
Mr. Linxed ・ Apr 20
Accomplish more with the "Cult of Done"
Mr. Linxed ・ Feb 18
Home Web Front-end JS Tutorial Space Defender - part Game States

Space Defender - part Game States

Jul 21, 2024 am 08:36 AM

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!

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

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1672
14
PHP Tutorial
1277
29
C# Tutorial
1256
24
Python vs. JavaScript: The Learning Curve and Ease of Use Python vs. JavaScript: The Learning Curve and Ease of Use Apr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

JavaScript and the Web: Core Functionality and Use Cases JavaScript and the Web: Core Functionality and Use Cases Apr 18, 2025 am 12:19 AM

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

JavaScript in Action: Real-World Examples and Projects JavaScript in Action: Real-World Examples and Projects Apr 19, 2025 am 12:13 AM

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

Understanding the JavaScript Engine: Implementation Details Understanding the JavaScript Engine: Implementation Details Apr 17, 2025 am 12:05 AM

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python vs. JavaScript: Community, Libraries, and Resources Python vs. JavaScript: Community, Libraries, and Resources Apr 15, 2025 am 12:16 AM

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

Python vs. JavaScript: Development Environments and Tools Python vs. JavaScript: Development Environments and Tools Apr 26, 2025 am 12:09 AM

Both Python and JavaScript's choices in development environments are important. 1) Python's development environment includes PyCharm, JupyterNotebook and Anaconda, which are suitable for data science and rapid prototyping. 2) The development environment of JavaScript includes Node.js, VSCode and Webpack, which are suitable for front-end and back-end development. Choosing the right tools according to project needs can improve development efficiency and project success rate.

The Role of C/C   in JavaScript Interpreters and Compilers The Role of C/C in JavaScript Interpreters and Compilers Apr 20, 2025 am 12:01 AM

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

From Websites to Apps: The Diverse Applications of JavaScript From Websites to Apps: The Diverse Applications of JavaScript Apr 22, 2025 am 12:02 AM

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

See all articles