body {
  margin: 0;
  padding: 40px 0 0 0;
  background: #222;
  color: #eee;
}
/* global Phaser */

var n = 1;

var PolygonGame = new Phaser.Class({

  Extends: Phaser.Scene,

  initialize: function PolygonGame () {
    Phaser.Scene.call(this, { key: 'polygongame' });
  },

  preload: function () {},

  create: function () {
    var scene = this;

    this.polygons = [];
    this.player;
    this.score = 0;
    this.isGameOver = false;

    this.createPlayer();
    this.polygons.push(this.createPolygon());
    this.matter.world.on('collisionstart', function (event) {
      this.isGameOver = true;
    }, this);
    this.displayHud();
    
    this.input.keyboard.on('keyup_R', function () {
      this.events.off('addScore');
      this.scene.restart();
    }, this);
  },

  displayHud: function () {
    var scene = this;
    var info = this.add.text(10, 10, 'Score: 0', {
      font: '48px Arial',
      fill: '#FFFFFF'
    });
    info.setName('info' + n++);
    info.on('destroy', function () {
      console.log('destroy', this.name);
    });
    this.events.on('addScore', function () {
      console.log('addScore', info.name);
      console.assert(info.scene !== null);
      scene.score += 1;
      info.setText('Score: ' + this.score);
    }, this);
    console.assert(this.events._events.addScore.length === 1);
    console.log('events [addScore]', this.events._events.addScore);
  },
  
  createPolygon: function () {
    var multiplier = 30;
    var rotationPosibilities = [0, 90, 280];
    var vert = [
      { x: 0 * multiplier, y: 0 * multiplier },
      { x: 15 * multiplier, y: 30 * multiplier },
      { x: 50 * multiplier, y: 30 * multiplier },
      { x: 65 * multiplier, y: 0 * multiplier },
      { x: 50 * multiplier, y: -30 * multiplier },
      { x: 15 * multiplier, y: -30 * multiplier },
      { x: 20 * multiplier, y: -25 * multiplier },
      { x: 45 * multiplier, y: -25 * multiplier },
      { x: 58 * multiplier, y: 0 * multiplier },
      { x: 47 * multiplier, y: 23 * multiplier },
      { x: 18 * multiplier, y: 23 * multiplier },
      { x: 7 * multiplier, y: 0 * multiplier }
    ];
    var polygonBody = this.add.polygon(
      game.config.width / 2,
      game.config.height / 2,
      vert,
      0x0000ff
    );
    var polygon = this.matter.add.gameObject(polygonBody, {
      shape: { type: 'fromVerts', verts: vert },
      render: { sprite: { xOffset: 0, yOffset: -0.5 } },
      isSensor: true
    });
    polygon.rotation = rotationPosibilities[Math.floor(Math.random() * Math.floor(4))];
    polygon.absoluteScale = 1;
    return polygon;
  },
  
  createPlayer: function () {
    var player = this.add.circle(
      game.config.width / 2,
      game.config.height / 2,
      20,
      0x6666ff
    );
    this.matter.add.gameObject(player, { isSensor: true });
    this.input.on('pointermove', function (pointer) {
      var center = new Phaser.Math.Vector2(
        game.config.width / 2,
        game.config.height / 2
      );
      var position = new Phaser.Math.Vector2(pointer.worldX, pointer.worldY)
        .subtract(center)
        .normalize()
        .scale(100)
        .add(center);
      player.setPosition(position.x, position.y);
    });
  },
  
  update: function () {
    if (this.isGameOver) {
      this.scene.start('polygongameend');
      return;
    }
    this.events.emit('addScore');
    var scene = this;
    scene.polygons.forEach(function (polygon, index, object) {
      polygon.setScale(polygon.absoluteScale);
      polygon.absoluteScale -= 0.004;
      polygon.rotation += 0.01;

      if (polygon.scaleX <= 0) {
        object.splice(index, 1);
        polygon.destroy();
      }
      if (scene.polygons.length < 2 && polygon.scaleX < 0.5) {
        scene.polygons.push(this.createPolygon(scene));
      }
    }, this);
  }
});

var PolygonGameEnd = new Phaser.Class({

  Extends: Phaser.Scene,

  initialize: function PolygonGameEnd () {
    Phaser.Scene.call(this, { key: 'polygongameend' });
  },

  create: function () {
    console.log('scene2');

    var info = this.add.text(10, 10, 'Fin du jeu', {
      font: '48px Arial',
      fill: '#FFFFFF'
    });
  }
});

var config = {
  type: Phaser.AUTO,
  width: 800,
  height: 600,
  physics: {
    default: 'matter',
    matter: {
      gravity: { y: 0 },
      debugShowInternalEdges: true,
      debug: true,
      debugShowConvexHulls: true
    }
  },
  scene: [PolygonGame, PolygonGameEnd],
  plugins: {
    global: [
      // <https://github.com/samme/phaser-plugin-scene-watcher/>
      {
        key: 'SceneWatcherPlugin',
        plugin: PhaserSceneWatcherPlugin,
        start: true
      }
    ]
  },
  callbacks: {
    postBoot: function (game) {
      game.scene.dump();
      game.plugins.get('SceneWatcherPlugin').watchAll();
    }
  }
};

var game = new Phaser.Game(config);
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/phaser/3.15.1/phaser.js
  2. https://cdn.jsdelivr.net/npm/phaser-plugin-scene-watcher@2.1.0/dist/PhaserSceneWatcherPlugin.js