Steps

Collectible Coins


Step 1 — Create a Spritesheet with an Image in the Boot Class**

In the Boot.ts file — add a method to preload() that loads a spritesheet into the game’s cache.

  • This method takes three arguments:
    1. Key — referring to the spritesheet ('coin')
    2. Path to the spritesheet file — images/coin_animated.png
    3. Object — specifying the width and height of each frame in the spritesheet.
// Boot.ts
export class Boot extends Phaser.Scene {
//...

preload() {
//...

this.load.spritesheet('coin', 'images/coin_animated.png', {
frameWidth: 22,
frameHeight: 22,
});
}

//...
}

Add audio for the coin

// Boot.ts
export class Boot extends Phaser.Scene {
//...

preload() {
//...

this.load.spritesheet('coin', 'images/coin_animated.png', {
frameWidth: 22,
frameHeight: 22,
});

this.load.audio('sfx:jump', 'audio/jump.wav');
**this.load.audio('sfx:coin', 'audio/coin.wav');**
}

//...
}

Step 2 — Add the Coins to the Level Class

In the constructor of Level.ts — which will create new instances of objects when a level is started — create a new “physics” group.

  • This should include an allowGravity option set to false — so that the coins stay in place and aren’t affected by gravity simulations in the game.
// Level.ts
export class Level {
//...

constructor(private scene: Play) {
//...
this.groups = {
players: this.scene.physics.add.group(),
coins: this.scene.physics.add.group({ allowGravity: false }),
};
}

//...
}

Step 3 — Create Methods that Spawn Coins in the Game as Part of the Level

Using the instance of coins that we’ve initiated in the constructor, we want to have a way to create multiple coins in the game and a way to cover creating just one coin at a time.

  • spawnCoins(coins) — This takes an array of coins as an argument.
    • Each coin in the array is its own object that contains the x and y coordinates for where the coin should be placed.
    • Use a forEach function to iterate over each coin in the coins array.
    • Each part of this process will call the singular spawnCoin() method to create one new coin and add that to the group of coins to be spawned.
    • The true reference ensures that the coin sprite will be immediately added to the scene.
  • spawnCoin(coin) — takes one coin object as an argument which contains the x and y coordinates for where the coin will be placed (data that is set in each JSON file for each level).
    • Next, the method uses: this.scene.add.sprite(coin.x, coin.y, 'coin'); to create a new sprite for the coin at the specific coordinates. This is how we are able to have multiple coins all set at different locations in the level.
    • The coin uses the coin image from the sprite which has been loaded into the game’s cache (in the Boot.ts file).
    • setOrigin(0.5, 0.5) sets the origin of a sprite to its center — this affects how the coin is positioned and rotated.
    • We return the new coin sprite at the end.
  • These two methods together create new coins in the game scene at specified locations.
// Level.ts
export class Level {
//...

spawnCoins(coins) {
coins.forEach((coin) => {
const _coin = this.spawnCoin(coin);
this.groups.coins.add(_coin, true);
});
}

spawnCoin(coin) {
const _coin = this.scene.add.sprite(coin.x, coin.y, 'coin');
_coin.setOrigin(0.5, 0.5);
return _coin;
}

//...
}

Activate the creation of coins in the loadLevel() method.

  • Add an argument of data.coins — this should be an array where each element is an object that contains the coordinates for spawning a coin in this level.
// Level.ts
export class Level {
//...

loadLevel(data) {
//...
this.spawnCoins(data.coins);
}

spawnCoins(coins) {
coins.forEach((coin) => {
const _coin = this.spawnCoin(coin);
this.groups.coins.add(_coin, true);
});
}

spawnCoin(coin) {
const _coin = this.scene.add.sprite(coin.x, coin.y, 'coin');
_coin.setOrigin(0.5, 0.5);
return _coin;
}

//...
}

Step 4 — Incorporate the Coins into Game Functionality — Play.ts

Add interaction between the hero and a coin:

  • The initPhysics() method initializes how physics works in the game between different objects.
  • Add an overlap between the hero and the coins that triggers other functions when the overlap happens.
  • We want to add a collectCoin() method when this happens.
  • undefined is a placeholder for a process callback so that we can perform additional checks before the overlap callback is executed.
  • this is the context in which the overlap callback is called.
// Play.ts
export class Play extends Phaser.Scene {
//...
initPhysics() {
this.physics.add.collider(this.hero, this.level.platforms);

this.physics.add.overlap(
this.hero,
this.groups.coins,
this.collectCoin,
undefined,
this
);
}

//...
}

Add the collectCoin() function that we’ve made a reference to.

  • This will configure what happens when the hero/coin overlap event occurs (i.e., a hero collects a coin).

  • The method should take two arguments: hero and coin — this is an instance of the Hero class and an instance of the Coin class that we’ve already established. Here, we are referring to those classes to use them in this event.

  • coin.destroy() is used to remove a game object. We want this to happen when a hero/coin overlap occurs.

  • this.sound.play('sfx:coin') — refers to the “sound” object to play a sound when the event occurs.

    • sfx:coin — is the key of the audio file to play which we have loaded into the game’s cache in Boot.ts.
// Play.ts
export class Play extends Phaser.Scene {
//...
initPhysics() {
this.physics.add.collider(this.hero, this.level.platforms);

this.physics.add.overlap(
this.hero,
this.groups.coins,
this.collectCoin,
undefined,
this
);
}

collectCoin(hero, coin) {
coin.destroy();
this.sound.play('sfx:coin');
}

//...
}

Checkpoint

  1. Coins should be accessible throughout the level.
  2. When the character moves over a coin — the coin should disappear and a sound should play. screenshot
< Back Home