phaser 3 reset the whole scene

Viewed 37

Following the phaser documentation, the scene restart is not working.

What I'm doing is the following, there are three scenes (start, play and end.). When it gets to the end, when clicking on the screen it gives this.scene.start('play'). I tried several ways, researched a lot and tried several things but the ones that worked in my case, the game for some events and some settings are not reset. For example, in this game you will create enemies and some packs. When it is restarted or started again, these builds are no longer executed.

Start

import Phaser from "phaser";

class Start extends Phaser.Scene{

    constructor ()
    {
        super({ key: 'start', active: true });
    }


    init(){
        console.log("- ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./pages/game/index.vue?vue&type=script&lang=js&")
        console.log("initiated 0418971")
        console.log("Unexpected console statement  no-console")
        console.log("bundle 'client' has 1 warnings")
        console.log("Caching create all")
        this.cameras.main.setBackgroundColor("#24252A");
    }

    preload(){

    }

    create() {
        this.helloWorld = this.add.text(
            this.cameras.main.centerX,
            this.cameras.main.centerY,
            "Clique para jogar",
            { font: "40px Arial",  fill: "#ffffff" }
          );
          this.helloWorld.setOrigin(0.5);

        this.input.on('pointerup', function (pointer) {

            this.scene.start('play');

        }, this);
    }

    update() {

    }

}

export default Start;

Play

import Phaser from "phaser";
// import Pack from '~/assets/game/Components/Pack.js'

class Play extends Phaser.Scene {

  constructor() {
    super({
      key: 'play',
      active: false
    });
  }

  index = 0;
  packs = Phaser.GameObjects.Group;
  enemys = Phaser.GameObjects.Group;
  spriteLife = [];

  config = {
    speed: 0,
    speedVelocity: 0.3,
    maxSpeed: 15,
    pack: {
      created: 0,
      limitcreate: 1,
      value: 4.5,
    },
    enemy: {
      speed: 5,
      created: 0,
      limitcreate: 1,
      x: 0,
    },
    engine: {
      temperature: 0,
    }
  };

  init() {
  }

  preload() {
    // Images
    this.load.image('grama', require('~/assets/game/assets/grama.jpg'));
    this.load.image('road', require('~/assets/game/assets/road-2.png'))
    this.load.image('pack', require('~/assets/game/assets/pack.png'));
    this.load.image('life', require('~/assets/game/assets/life.png'));

    // Sprite sheet
    this.load.spritesheet('player', require('~/assets/game/assets/car-sprite.png'), {
      frameWidth: 404,
      frameHeight: 1009
    })
  }

  createGram() {
    let a = 0;
    let b = 0;
    const totalA = 8;
    const totalB = 4;

    for (a = 0; a <= totalA; a++) {
      for (b = 0; b <= totalB; b++) {
        const grama = this.add.sprite(0, 0, 'grama').setScale(0.2);
        grama.setPosition(grama.displayWidth * b, grama.displayHeight * a);

      }
    }
  }

  createScore() {
    this.score = 0;

    this.scoreText = this.add.text(15, 45,
      `SCORE: 0`, {
        font: "20px Arial",
        fill: "#ffffff"
      }
    );
  }

  createLife() {
    this.numberLifes = 3;

    this.add.text(15, 15,
      `LIFE:`, {
        font: "20px Arial",
        fill: "#ffffff"
      }
    );

    for (let i = 0; i < this.numberLifes; i++) {
      this.spriteLife.push(this.add.image(80 + 30 * i, 25, 'life').setScale(0.09))
    }
  }

  createPlayer() {
    this.player = this.physics.add.sprite(0, 0, 'player');
    this.player.setOrigin(0.5)
    this.player.setScale(0.2);
    this.player.setPosition(this.cameras.main.centerX, this.cameras.main.displayHeight - 120);

    this.player.setCollideWorldBounds(true);
  }

  createPack() {
    if(this.config.pack.created < this.config.pack.limitcreate){
      this.packs.create(Phaser.Math.Between(60, 330), 0, 'pack').setScale(.15).setOrigin(.5);
      this.config.pack.created += 1;
    }
  }

  createEnemy() {
    if(this.config.enemy.created < this.config.enemy.limitcreate){
      this.enemy = this.enemys.create(Phaser.Math.Between(70, 320), -200, 'player').setScale(.2).setOrigin(.5);
      this.enemy.anims.play('default', true);
      this.config.enemy.created += 1;
      this.config.enemy.x = this.enemys.children.entries[0].x;
    }
  }

  createEngineTemperatureBar() {
    this.engineTemperatureBar = this.add.graphics();
    this.engineTemperatureBar.fillStyle(0xffffff, 1);
    this.engineTemperatureBar.fillRect(0, 0, 130, 30);

    // Position
    this.engineTemperatureBar.x = 350;
    this.engineTemperatureBar.y = 830;
    this.engineTemperatureBar.angle = -90;
    this.engineTemperatureBar.scaleX = 0;
  }

  myAnims() {
    this.anims.create({
      key: 'left',
      frames: this.anims.generateFrameNumbers('player', {
        start: 4,
        end: 4
      }),
      frameRate: 3,
      repeat: 0
    })

    this.anims.create({
      key: 'right',
      frames: this.anims.generateFrameNumbers('player', {
        start: 0,
        end: 1
      }),
      frameRate: 3,
      repeat: 0
    })

    this.anims.create({
      key: 'default',
      frames: [{
        key: 'player',
        frame: 2
      }],
      frameRate: 20
    });
  }

  addPhysics(){
    // Add
    this.packs = this.physics.add.group();
    this.enemys = this.physics.add.group();

    // Collider
    this.physics.add.collider(this.player, this.packs, this.collectPack, null, this);
    this.physics.add.collider(this.player, this.enemys, this.collideEnemy, null, this, this.enemys);
  }

  create() {
    // Camera
    this.cameras.main.setBackgroundColor("#24252A");

    // Gram
    this.createGram();

    // Roads
    this.roads = this.add.tileSprite((this.game.canvas.clientWidth / 2), 0, 500, 1210, 'road').setOrigin(0.5, 0).setScale(0.7);

    // Functions
    this.createScore();
    this.createLife();
    this.createPlayer();
    this.myAnims();
    this.addPhysics();
    this.createEngineTemperatureBar();

    // Body
    this.packs.enableBody = true;
    this.enemys.enableBody = true;

    // Cursors
    this.cursors = this.input.keyboard.createCursorKeys();
  }

  update(time) {
    this.roads.tilePositionY -= this.config.speed;

    this.movePlayerManager();
    this.createPack();
    this.createEnemy();
    this.movePacks();
    this.moveEnemy()
    this.updateEngineTemperatureBar()
  }

  movePlayerManager() {
    // Left
    if (this.cursors.left.isDown) {
      this.player.x -= 5;
      this.player.anims.play('left', false);
    }
    // Right
    else if (this.cursors.right.isDown) {
      this.player.x += 5;
      this.player.anims.play('right', false);
    }
    else {
      this.player.anims.play('default', true);
    }

    // Up
    if (this.cursors.up.isDown) {
      // Increase speed
      if (this.config.speed <= this.config.maxSpeed){
        this.config.speed += this.config.speedVelocity;
      }
    }

    if (this.cursors.up.isUp) {
      if (this.config.speed > 0){
        this.config.speed -= 0.5;
      }
      else
        this.config.speed = 0
    }

  }

  movePacks() {
    this.packs.children.each((e) => {
      e.y += this.config.speed;

      if(e.y > this.game.config.height){
        e.destroy();
        this.config.pack.created -= 1;
      }
    })
  }

  moveEnemy() {
    this.enemys.children.each((e) => {
      if(this.cursors.up.isDown){
        if(this.config.speed < this.config.maxSpeed-1){
          e.y -= this.config.maxSpeed;
          return
        };
          
        e.y += this.config.enemy.speed;

        // Move left or right
        if(this.config.enemy.x < 150 && e.x < 290){
          e.x += 1;
          this.enemy.anims.play('right', true);
        }
        else if(e.x > 90){
          e.x -= 1;
          this.enemy.anims.play('left', true);
        }else{
          this.enemy.anims.play('default', true);
        }
      }else{
        if(e.y < -1000) return;

        e.y -= this.config.maxSpeed;
      }

      if(e.y - 200 > this.game.config.height){
        e.destroy();
        this.config.enemy.created -= 1;
      }
    })
  }

  updateEngineTemperatureBar(){
    if(this.cursors.up.isDown && this.config.engine.temperature <= 100){
      this.config.engine.temperature += 0.1;
    }
    else if(this.cursors.up.isUp && this.config.engine.temperature < 100){
      this.config.engine.temperature += 0.2;
    }else{
      this.scene.start('end', { motiveText: "O motor do seu carro explodiu." });
    }

    // change the size of the bar
    this.engineTemperatureBar.scaleX = this.config.engine.temperature/100;
  }

  updateLifes(){
    if(this.numberLifes <= 1){
      this.scene.start('end', { motiveText: "Suas vidas acabaram." });
    }else{
      this.spriteLife[this.numberLifes-1].destroy();
      this.numberLifes = this.numberLifes -1;
    }
  }

  collectPack(player, pack){
    // Destroy pack
    pack.disableBody(true, true);
    pack.destroy();

    // Config
    this.config.pack.created -= 1;

    // Score
    this.score++;
    this.scoreText.setText("SCORE: " + this.score);

    // Engien temperature bar
    if(this.config.engine.temperature > 1)
      this.config.engine.temperature -= this.config.pack.value;
  }

  collideEnemy(player, enemy){
    // Life
    this.updateLifes();
    
    // Destroy
    enemy.destroy();
    
    // Config
    this.config.speed = 1;
    this.config.enemy.created -= 1;
  }
}

export default Play;

End

import Phaser from "phaser";

class End extends Phaser.Scene{

    constructor ()
    {
        super({ key: 'end', active: false });
    }


    init(data){
        this.motiveText = data.motiveText;
    }
    
    preload(){
        
    }
    
    create() {
        this.helloWorld = this.add.text(
            this.cameras.main.centerX,
            this.cameras.main.centerY,
            "Perdeu!",
            { font: "40px Arial",  fill: "#ffffff" }
        );
        this.helloWorld.setOrigin(0.5);
        
        this.helloWorld = this.add.text(
            this.cameras.main.centerX,
            this.cameras.main.centerY + 40,
            this.motiveText,
            { font: "20px Arial",  fill: "#ffffff" }
        );
        this.helloWorld.setOrigin(0.5);

        this.helloWorld = this.add.text(
            this.cameras.main.centerX,
            this.cameras.main.centerY + 70,
            "Clique para jogar novamente.",
            { font: "20px Arial",  fill: "#ffffff" }
        );
        this.helloWorld.setOrigin(0.5);

        this.input.on('pointerup', function (pointer) {

            this.scene.start("start");

        }, this);
    }

    update() {

    }

}

export default End;

Again, the problem is that he doesn't completely rest. Even using the 'restart' methods, destroying the events and restarting them.

1 Answers

The issue is, that your are setting properties on the Scenes classes, like the property config on the Play class. Since these properties are not set in the create or the init function, they will never be reset, on start/ restart.
When the Scenes are restarted, scenes are not recreated, so properties are not reset and the constructor is also not called.

If you need to define / set properties on the Scenes, the best solution would be to always (re)set them in the init or create function, since these functions are called on start or restart.

I would recomend, simply moving the properties from the Play class into the init method like this:

 class Play extends Phaser.Scene {
     ...
     init() {
         this.index = 0;
         this.packs = Phaser.GameObjects.Group;
         this.enemys = Phaser.GameObjects.Group;
         this.spriteLife = [];

         this.config = {
             speed: 0,
             speedVelocity: 0.3,
             maxSpeed: 15,
             pack: {
                ...
             },
             enemy: {
                 ...
             },
             engine: {
                 temperature: 0,
             }
         };
      }
      ...
 }
Related