Phaser3 场景切换错误。我能怎么做?

Phaser3 Scene switching error. How can i do?

碰墙换场景出现这个错误:

Cannot read properties of undefined (reading 'start')

我尝试了几种技术,但 none 有效,但我没有其他错误,我的代码非常简单,我不明白为什么它不起作用... 这是我的代码:

class SceneMilieu extends Phaser.Scene {

  constructor() {
   super({key: 'sceneMilieu'});
 }


  //Chargement des images
  preload() {
    // this.load.image("Backgrond", "javascript/assets/Background.png");
    this.load.image("player", "javascript/assets/player.png");
    this.load.image("run1", "javascript/assets/run1.png");
    this.load.image("run2", "javascript/assets/run2.png");
    this.load.image("playerLeftRun1", "javascript/assets/playerLeftRun1.png");
    this.load.image("playerLeftRun2", "javascript/assets/playerLeftRun2.png");
    this.load.image("wall", "javascript/assets/wall.png");

  }

  create() {
    cursor = this.input.keyboard.createCursorKeys(); //touches des fleches

    var w = config.width;
    var h = config.height;

    //Les animations
    this.anims.create({
      key : "playerWalkUp",
      frames : [
        {key : "run1"},
        {key : "run2"}],
      frameRate : 7,
      repeat : 0
    })

    this.anims.create({
      key : "playerWalkLeft",
      frames : [
        {key : "playerLeftRun1"},
        {key : "playerLeftRun2"}],
      frameRate : 7,
      repeat : 0
    })

    // L'apparition + le controle et les collisions ce fais ci dessous

    // var backgroundImage = this.add.sprite(0, 0, "Background");
    // backgroundImage.setPosition(w/2, h/2);
    player = this.physics.add.sprite(100, 300, "player"); //joueur
    player.setScale(1);
    player.body.setSize(30, 35);
    player.setCollideWorldBounds(true); //collision avec la bordure

    doorLeft = this.physics.add.staticSprite(200, 400, "wall"); //Porte de tp

    var platforms = this.physics.add.staticGroup();

    var wall = this.add.sprite(400, 500, "wall"); //mur
    

    this.physics.add.collider(platforms, player); //collision

    platforms.add(wall);
    
    function collision() {
      this.scene.start("sceneGauche");  
    }
    
    this.physics.add.collider(player, doorLeft, collision);
  }

  update() {

  // Tous les mouvement sont controler par ce code

    if (cursor.left.isDown){
      player.setVelocityX(-200); //vitesse de deplacements
      player.anims.play("playerWalkLeft", true); //animations du personnage
      player.setFlip(false, false); //oriantation de l'image
    } else if (cursor.right.isDown){
      player.setVelocityX(200);
      player.anims.play("playerWalkLeft", true);
      player.setFlip(true, false);
    } else if (cursor.up.isDown){
      player.setVelocityY(-200);
      player.anims.play("playerWalkUp", true);
      player.setFlip(false, false);
    } else if (cursor.down.isDown){
      player.setVelocityY(200);
      player.anims.play("playerWalkUp", true);
      player.setFlip(false, true);
    } else {
      player.setVelocity(0);
      player.setTexture("player");
    }

    if ((cursor.left.isDown && cursor.up.isDown) || (cursor.left.isDown && cursor.right.isDown) || (cursor.left.isDown && cursor.down.isDown) || (cursor.right.isDown && cursor.up.isDown) || (cursor.right.isDown && cursor.down.isDown)){
      player.setVelocity(0);
      player.setTexture("player");
    }

  //--------

}}

class SceneGauche extends Phaser.Scene {

  constructor() {
    super({key: "SceneGauche"});
    scene: {
      preload: this.preload;
      create: this.create;
      update: this.update;
    }
  }

  preload() {
    this.load.image("player", "javascript/assets/player.png");
    this.load.image("run1", "javascript/assets/run1.png");
    this.load.image("run2", "javascript/assets/run2.png");
    this.load.image("playerLeftRun1", "javascript/assets/playerLeftRun1.png");
    this.load.image("playerLeftRun2", "javascript/assets/playerLeftRun2.png");
    this.load.image("wall", "javascript/assets/wall.png");

  }

  create() {
    cursor = this.input.keyboard.createCursorKeys();

    var w = config.width;
    var h = config.height;

    this.anims.create({
      key : "playerWalkUp",
      frames : [
        {key : "run1"},
        {key : "run2"}],
      frameRate : 7,
      repeat : 0
    })

    this.anims.create({
      key : "playerWalkLeft",
      frames : [
        {key : "playerLeftRun1"},
        {key : "playerLeftRun2"}],
      frameRate : 7,
      repeat : 0
    })

    player = this.physics.add.sprite(100, 300, "player");
    player.setScale(1);
    player.body.setSize(30, 35);
    const border = player.setCollideWorldBounds(true);

    var platforms = this.physics.add.staticGroup();

    var wall = this.add.sprite(400, 500, "wall");
    platforms.add(wall);

    this.physics.add.collider(platforms, player); 

    player.onCollide = new Phaser.signal(); 
    border.onCollide.add(changeMapGauche, this);

  }

  update() {

    if (cursor.left.isDown){
      player.setVelocityX(-200);
      player.anims.play("playerWalkLeft", true);
      player.setFlip(false, false);
    } else if (cursor.right.isDown){
      player.setVelocityX(200);
      player.anims.play("playerWalkLeft", true);
      player.setFlip(true, false);
    } else if (cursor.up.isDown){
      player.setVelocityY(-200);
      player.anims.play("playerWalkUp", true);
      player.setFlip(false, false);
    } else if (cursor.down.isDown){
      player.setVelocityY(200);
      player.anims.play("playerWalkUp", true);
      player.setFlip(false, true);
    } else {
      player.setVelocity(0);
      player.setTexture("player");
    }

    if ((cursor.left.isDown && cursor.up.isDown) || (cursor.left.isDown && cursor.right.isDown) || (cursor.left.isDown && cursor.down.isDown) || (cursor.right.isDown && cursor.up.isDown) || (cursor.right.isDown && cursor.down.isDown)){
      player.setVelocity(0);
      player.setTexture("player");
    }
  }

}

var config = {
  type: Phaser.AUTO,
  width: window.innerWidth - 20,
  height: window.innerHeight - 100,
  backgroundColor: "#EDEED0",
  physics: {
    default : "arcade",
    arcade : {
      debug : true,
    }
  },
  scene: [SceneMilieu, SceneGauche]
};

let game = new Phaser.Game(config);

var cursor;
var player;
var doorLeft; 

<!-- begin snippet: js hide: false console: true babel: false -->
<!DOCTYPE html>
<html lang="fr-FR">

  <head>

    <meta charset="utf-8" />
    <meta name="description" content="Page web du projet de NSI. Ce site regrouppe quelque jeux en ligne programmer par nous même en javascript" />
    <meta name="author" content="Thorvald Helbling, Alexis STOCK, Lionel FUCHS" />
    <title>Thoralial</title>
    <link rel="stylesheet" type="text/css" href="style.css" />
    <script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>

  </head>

  <header>

    <img id="LogoThoralial" src="info/image/LogoThoralial.png" alt="Logo du site" />

    <div>
      <h1>Bienvenue !</h1>
      <p>C'est votre tableau de bord.</p>
    </div>

  </header>

  <body>

    <script id="js" type="text/javascript" src="javascript/main.js"></script>
    <script></script>

  </body>

  <footer>
    
    <div id="personne">
      <p>
        Ce projet a étais réalisé par : <a href="***"> Thorvald HELBLING</a>, <a href="***"> Lionel FUCHS </a> et <a href="***"> Alexis STOCK </a>
      </p>
    </div>

  </footer>
</html>

我想了解我的错误从何而来,并共同修复了它。 我用Phaser3 错误来自站点控制台。 (本地)

问题是这行代码:

 this.physics.add.collider(player, doorLeft, collision);

您只需将 scene 作为上下文传递给 collider 函数。这是文档的 link,特别是 collider 函数和参数。 https://newdocs.phaser.io/docs/3.52.0/focus/Phaser.Physics.Arcade.Factory-collider

换句话说,您只需传递 scene 上下文(作为参数 5)和 应该处理函数 (参数 4,在本例中为 undefined, 因为没有函数)

只需用这一行替换当前行(或添加两个参数),它应该可以工作

  this.physics.add.collider(player, doorLeft, collision, undefined, this);

或者您可以使用 javascript 函数 bind:

  this.physics.add.collider(player, doorLeft, collision.bind(this));

可能不那么明显,但它更短并且工作正常 (Link to bind documentaion)。这将是我的首选方法,如果 我不使用参数 4,因为这样代码更简洁更短。

更新: 或者,如果您想使用 Closures,您可以仅将函数定义更改为 arrow function expression,那么你就不必传递任何额外的参数,执行 collider 函数:

   let collision = () => {
       this.scene.start("sceneGauche");  
   }

I'm in usually no fan of defining functions inside of function/methods (especially with the function keyword), but with the arrow function expression, it's looks even abit cleaner.