【问题标题】:Phaser 3: How to stop scene?Phaser 3:如何停止场景?
【发布时间】:2022-01-13 19:48:53
【问题描述】:

这是 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 });
}

【问题讨论】:

    标签: javascript phaser-framework


    【解决方案1】:

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

    我会说问题不是this.scene.stop("game"),虽然我只会使用this.scene.stop(),如果你想停止当前的scenein 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)
      

    它应该“工作”。

    顺便说一句:如果您有错误/问题/... 使用 html/javscript 始终检查浏览器控制台,这可以帮助您更快地找到错误。

    【讨论】:

    • 非常感谢您的回复!我试过了,它就像一个魅力!不过有一个问题——场景对象的意义何在?
    • scene 对象或多或少是绘制所有内容的屏幕。在官方移相器页面上查看这个简短的示例:phaser.io/examples/v3/category/scenes,它们比我能更好地解释场景对象的功能。 :)
    猜你喜欢
    • 2022-09-23
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多