Phaser 3:如何停止场景?

Phaser 3: How to stop scene?

这是 Codecademy 实践中的一个代码。 I am trying to end scene when the option text says Play again.基本上我想要的是一个特定的选项将允许我退出场景并进入一个新场景。 (即游戏结束时) 我尝试使用

if (optionText==="Play again"){
        optionBox.on('pointerup', function() {
          this.scene.stop("game")
      
      })}

我已经注释掉了第116行的代码

但它只是使代码崩溃。

let gameState = {}

function preload () {
  // load in background and characters
  this.load.image('bg',     'https://content.codecademy.com/projects/learn-phaser/cyoa/background.png');
  this.load.image('knight', 'https://content.codecademy.com/projects/learn-phaser/cyoa/knight.png');
  this.load.image('orc',    'https://content.codecademy.com/projects/learn-phaser/cyoa/orc.png');
  this.load.image('wizard', 'https://content.codecademy.com/projects/learn-phaser/cyoa/wizard.png');
}
function create(){
  gameState.background=this.add.image(0,0,"bg")
  gameState.background.setOrigin(0,0);
  gameState.character=renderCharacter(this,"knight");
  initializePage(this);
  const firstPage=fetchPage(1);
  displayPage(this,firstPage)
}
function renderCharacter(scene,key){
  if (gameState.character){
    gameState.character.destroy();}
    gameState.character=scene.add.image(270,340,key);
        gameState.character.setOrigin(0.5,1);
    gameState.character.setScale(0.7); }



function initializePage(scene) {
  // create options list and background
  // and saves them into gameState

  if (!gameState.options) {
    // create options list
    // if it doesn't exist
    gameState.options = [];
  }

  if (!gameState.narrative_background) {
    // create narrative background
    // if it doesn't exist
    gameState.narrative_background = scene.add.rectangle(10, 360, 430, 170, 0x000);
  gameState.narrative_background.setOrigin(0, 0);
  }
}

function destroyPage() {
  // wipe out narrative text and options

  if (gameState.narrative) {
    // destroy narrative if it exists
    gameState.narrative.destroy();
  }

  for (let option of gameState.options) {
    // destroy options if they exist
    option.optionBox.destroy();
    option.optionText.destroy();
  }
}

function displayPage(scene, page) {
  renderCharacter(scene,page.character);
  const narrativeStyle = { fill: '#ffffff', fontStyle: 'italic', align: 'center', wordWrap: { width: 340 }, lineSpacing: 8};
  
  // display general page character
  // & narrative here:
  gameState.narrative = scene.add.text(65, 380, page.narrative, narrativeStyle);

  // for-loop creates different options

  // need the index i for spacing the boxes
  for (let i=0; i<page.options.length; i++) {
    let option = page.options[i];

    // color in the option box
    const optionBox = scene.add.rectangle(40 + i * 130, 470, 110, 40, 0xb39c0e, 0)
    optionBox.strokeColor = 0xb39c0e;
    optionBox.strokeWeight = 2;
    optionBox.strokeAlpha = 1;
    optionBox.isStroked = true;
    optionBox.setOrigin(0, 0)
    

    // add in the option text
    const baseX = 40 + i * 130;
    const optionText = scene.add.text(baseX, 480, option.option, { fontSize:14, fill: '#b39c0e', align: 'center', wordWrap: {width: 110}});
    const optionTextBounds = optionText.getBounds()

    // centering each option text
    optionText.setX(optionTextBounds.x + 55 - (optionTextBounds.width / 2));
    optionText.setY(optionTextBounds.y + 10 - (optionTextBounds.height / 2));

    // add in gameplay functionality
    optionBox.setInteractive()
    // for options here

optionBox.on('pointerout', function() {
 this.optionBox.setStrokeStyle(1, 0xb38c03, 1);
this.optionText.setColor('#b39c0e');},  {optionBox, optionText })
  optionBox.on('pointerover', function() {
 this.optionBox.setStrokeStyle(2, 0xffe014, 1);this.optionText.setColor('#ffe014');}
, { optionBox, optionText })
    optionBox.on('pointerup',function(){
      const newPage=this.option.nextPage;
      if (newPage!==undefined){
        destroyPage()
        displayPage(scene,fetchPage(newPage));
      }

    },{option})

 gameState.options.push({
    optionBox,optionText
  })
    
  }
  /* this did NOT work
    if (optionText==="Play again"){
        optionBox.on('pointerup', function() {
          this.scene.stop("game")
      
      })}*/
}

const config = {
  type: Phaser.WEBGL,
  parent: 'phaser-game',
  backgroundColor: 0xfea0fd,
  width: 450,
  height: 550,
  scene: {
    preload,
    create,
  }
};

const game = new Phaser.Game(config);

function fetchPage(page) {


   const pages = [
     {
      character: 'orc',
      page: 1,
      narrative: 'Orc: Hello?',
      options: [
        { option: 'Say Hi',   nextPage: 2 },
        { option: 'Play again',   nextPage: 41 },
      ]
    },



  return pages.find(function(e) { if(e.page == page) return e });
}

我假设您为我们简化了代码,因此请忽略第 150 行缺少的 ] 和第 141+ 行 pages 常量中缺少的页码 41

我会说问题是 而不是 this.scene.stop("game"),虽然我只会使用 this.scene.stop(),如果你想停止当前 [=16] =] (in to a Reference ).

你可以看到问题,如果你取消注释代码并检查浏览器控制台,会出现如下错误:

"...Uncaught ReferenceError: optionText is not defined..."

应该是可见的。这表明真正的问题是 optionText 未定义。在不深入研究您的代码的情况下,这里有一些使其正常工作的修复程序:

  • 将整个块移动到 for 循环中。 (就在第 115 行的 } 上方)

  • if(optionText=== "Play again") 更改为 if(optionText.text === "Play again"),因为 optionTexttext 对象而不是字符串。

  • scene 对象作为上下文添加到 optionBox.on('pointerup',... 事件监听器 像这样:

      optionBox.on('pointerup', function () {
          this.scene.stop("game")
      }, scene)
    

它应该“有效”。

btw.: If you have Errors/Problems/... with html/javscript always check the browser console, this can help you find the error much faster.