class Example extends Phaser.Scene {
  preload() {
    this.load.image(
      "bullet",
      "https://assets.codepen.io/9367036/1bit-projectile.png"
    );
    this.load.image(
      "ship",
      "https://assets.codepen.io/9367036/1bit-player.png"
    );
    this.load.image(
      "starfield",
      "https://assets.codepen.io/9367036/background_1.png"
    );
  }

  create() {
    // Background
    this.stars = this.add
      .tileSprite(0, 0, config.width, config.height, "starfield")
      .setOrigin(0, 0);

    // Joueur
    this.player = this.physics.add.sprite(256, config.height - 50, "ship");
    this.player.setScale(2);
    this.bullets = this.physics.add.group({
      defaultKey: "bullet",
      maxSize: 10
    });

    // Événements / Controles
    this.input.on("pointermove", (pointer) => {
      this.player.x = pointer.worldX;
    });
    this.input.on("pointerdown", () => {
      const bullet = this.bullets.get(this.player.x, this.player.y);
      if (bullet) {
        bullet.setActive(true);
        bullet.setVisible(true);
        bullet.setVelocity(0, -200);
      }
    });
  }

  update() {
    // Lorsqu'une balle sort de la zone visible du jeu, on la désactive et on la cache.
    this.bullets.children.each((bullet) => {
      let cachee = !this.cameras.main.worldView.contains(bullet.x, bullet.y);
      if (bullet.active && cachee) {
        bullet.setActive(false);
        bullet.setVisible(false);
      }
    });
  }
}

const config = {
  type: Phaser.AUTO,
  width: 800,
  height: 400,
  pixelArt: true,
  parent: "phaser-example",
  physics: {
    default: "arcade",
    arcade: { debug: true }
  },
  scene: Example
};

const game = new Phaser.Game(config);

activateControls(["LMB"]);
Run Pen

External CSS

  1. https://codepen.io/tim-momo/pen/yLWvyra.css
  2. https://fonts.googleapis.com/css2?family=DotGothic16&display=swap

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/phaser/3.85.1/phaser.min.js
  2. https://codepen.io/tim-momo/pen/yLWvyra.js