Your First PhaserJS Game

Level Design

Learn to design game levels in PhaserJS by adding platforms, obstacles, and collectables to create a dynamic 2D environment.

Welcome to Chapter 4 of our game journey! 🎮 So far, we've covered how to add images, sprites, and animations into our scene. We’ve got our background set, and our main character is alive with animations.

But what's a game without some solid platforms, tricky obstacles, and juicy collectables? 🍎 That's what this chapter is all about—designing the level! Here, we'll add platforms, ground, spikes, and collectables to make our game world more interesting.


Step 1: Animations for Level Elements 🎨

Before adding these new elements, we need some animations for certain objects like falling platforms, apples, and trampolines. You already know how to create animations, so let's add a few more.

In your loadingScene.js file, add the following code inside the create function:

// Falling platform animation
this.anims.create({
    key: "falling_platform_on_anim",
    frames: this.anims.generateFrameNumbers("falling_platform_on", {
        start: 0,
        end: 3
    }),
    frameRate: 12,
    repeat: -1
});
 
// Apple animation
this.anims.create({
    key: "apple_anim",
    frames: this.anims.generateFrameNumbers("apple", {
        start: 0,
        end: 16
    }),
    frameRate: 20,
    repeat: -1
});
 
// Trampoline jump animation
this.anims.create({
    key: "trampoline_jump_anim",
    frames: this.anims.generateFrameNumbers("trampoline_jump", {
        start: 0,
        end: 7
    }),
    frameRate: 20,
    repeat: 0
});

Step 2: Adding Grounds and Platforms 🏞️

Let’s build the ground where our character can walk and jump, along with some platforms for extra challenge. Add the following function in mainScene.js:

addGrounds() {
    for(let i=0; i < 18; i++) {
        this.add.image(i * 46, this.game.config.height - 46, "ground").setOrigin(0, 0);
    }
 
    for(let i=0; i < 8; i++) {
        this.add.image(i * 46, 500, "ground").setOrigin(0, 0);
    }
 
    for(let i=0; i < 3; i++) {
        this.add.image(200 + i * 46, 200, "ground").setOrigin(0, 0);
    }
 
    for(let i=0; i < 3; i++) {
        this.add.image(440 + i * 46, 200, "ground").setOrigin(0, 0);
    }
}

Now, let’s add some platforms for variety and challenge:

addPlatforms() {
    this.add.image(480, 580, "platform_brown").setScale(2.5);
    this.add.image(630, 680, "platform_grey").setScale(2.5);
    this.add.image(60, 400, "platform_grey").setScale(2.5);
 
    const falling_platform_1 = this.add.sprite(630, 270, "falling_platform_on").setScale(2.5);
    falling_platform_1.anims.play("falling_platform_on_anim", true);
 
    const falling_platform_2 = this.add.sprite(150, 300, "falling_platform_on").setScale(2.5);
    falling_platform_2.anims.play("falling_platform_on_anim", true);
}

Step 3: Adding Collectables 🍎

What’s a level without something to collect? Let’s add some apples to keep things fun and rewarding:

addCollectables() {
    const apple1 = this.add.sprite(270, 180, "apple").setScale(2);
    apple1.anims.play("apple_anim", true);
 
    const apple2 = this.add.sprite(510, 180, "apple").setScale(2);
    apple2.anims.play("apple_anim", true);
 
    const apple3 = this.add.sprite(210, 470, "apple").setScale(2);
    apple3.anims.play("apple_anim", true);
}

The apples will animate (thanks to our earlier animation setup) and appear at different positions for the player to collect.


Step 4: Adding the Trampoline 🤸‍♂️

Lastly, let’s add a trampoline to boost our player up:

addTrampoline() {
    const trampoline = this.add.sprite(765, 720, "trampoline_idle").setScale(2.5);
}

The trampoline won’t have any immediate animation, but it's there waiting for some bouncing action in future chapters!


Step 5: Bringing It All Together 🔗

Finally, we need to call all these functions to render the level design on the screen. Inside the create() function of mainScene.js, add the following lines:

this.addGrounds();
this.addPlatforms();
this.addCollectables();
this.addTrampoline();

And that’s it! You’ve successfully designed your level with platforms, ground, collectables, and a trampoline. 🎉

06


Conclusion 🎓

Congratulations! 🎊 You've learned how to design a level in PhaserJS by adding different elements like grounds, platforms, and collectables. Remember, you can tweak the positions and quantities of these elements to design your own custom levels. 🛠️ Get creative!

In the next chapter, we will breathe life into this level by adding physics, gravity, and collision detection to make everything interactable and dynamic!


Complete Code 📜

If you missed anything or made some accidental changes, here’s the complete code for reference! 💻🔧


import Phaser from "phaser";
 
export default class LoadingScene extends Phaser.Scene {
    constructor() {
        super({
            key: "LoadingScene"
        });
    }
 
    preload() {
        // background
        this.load.image("bg", "assets/bg.png");
 
        // ground
        this.load.image("ground", "assets/ground.png");
 
        // spike
        this.load.image("spike", "assets/spike.png");
 
        // items
        this.load.spritesheet("apple", "assets/Items/Apple.png", {
            frameWidth: 32,
            frameHeight: 32
        });
        this.load.spritesheet("collected", "assets/Items/Collected.png", {
            frameWidth: 32,
            frameHeight: 32
        });
 
        // main character
        this.load.spritesheet("player_idle", "assets/character/idle.png", {
            frameWidth: 32,
            frameHeight: 32
        });
        this.load.spritesheet("player_hit", "assets/character/hit.png", {
            frameWidth: 32,
            frameHeight: 32
        });
        this.load.spritesheet("player_jump", "assets/character/jump.png", {
            frameWidth: 32,
            frameHeight: 32
        });
        this.load.spritesheet("player_run", "assets/character/run.png", {
            frameWidth: 32,
            frameHeight: 32
        });
 
        // platforms
        this.load.image("platform_brown", "assets/Platforms/Brown.png");
        this.load.image("platform_grey", "assets/Platforms/Grey.png");
 
        // falling platforms
        this.load.image("falling_platform_off", "assets/FallingPlatforms/Off.png");
        this.load.spritesheet("falling_platform_on", "assets/FallingPlatforms/On.png", {
            frameWidth: 32,
            frameHeight: 10
        });
 
        // Trampoline
        this.load.image("trampoline_idle", "assets/Trampoline/Idle.png");
        this.load.spritesheet("trampoline_jump", "assets/Trampoline/Jump.png", {
            frameWidth: 28,
            frameHeight: 28
        });
    }
 
    create() {
        // main character animations
        this.anims.create({
            key: "player_idle_anim",
            frames: this.anims.generateFrameNumbers("player_idle", {
                start: 0,
                end: 10
            }),
            frameRate: 20,
            repeat: -1
        });
        this.anims.create({
            key: "player_hit_anim",
            frames: this.anims.generateFrameNumbers("player_hit", {
                start: 0,
                end: 6
            }),
            frameRate: 12
        });
        this.anims.create({
            key: "player_jump_anim",
            frames: this.anims.generateFrameNumbers("player_jump", {
                start: 0,
                end: 0
            })
        });
        this.anims.create({
            key: "player_run_anim",
            frames: this.anims.generateFrameNumbers("player_run", {
                start: 0,
                end: 11
            }),
            frameRate: 20,
            repeat: -1
        });
 
        // falling platform animation
        this.anims.create({
            key: "falling_platform_on_anim",
            frames: this.anims.generateFrameNumbers("falling_platform_on", {
                start: 0,
                end: 3
            }),
            frameRate: 12,
            repeat: -1
        });
 
        // apple animation
        this.anims.create({
            key: "apple_anim",
            frames: this.anims.generateFrameNumbers("apple", {
                start: 0,
                end: 16
            }),
            frameRate: 20,
            repeat: -1
        });
 
        // Trampoline Jump Animation
        this.anims.create({
            key: "trampoline_jump_anim",
            frames: this.anims.generateFrameNumbers("trampoline_jump", {
                start: 0,
                end: 7
            }),
            frameRate: 20,
            repeat: 0
        });
 
        this.scene.start("MainScene");
    }
 
    update() {
        // Nothing here for now, you can add logic as needed
    }
}

Now you have everything! 🚀 Enjoy creating your awesome PhaserJS game!

On this page