如何通过 JSONP 将资产加载到 Phaser 中

How to load assets via JSONP into Phaser

提问人:jurgenizer 提问时间:4/21/2023 更新时间:4/21/2023 访问量:71

问:

我正在尝试通过 JSONP 馈送将数据(包括图像)加载到 Phaser 3.60.0 中。我知道如何根据下面的GameScene.js代码正常加载图像资产:

class GameScene extends Phaser.Scene {
  constructor() {
    super({ key: 'GameScene' });
  }

  preload() {
    this.load.image('oranges', './assets/Ambersweet_oranges.jpg');
  }

  create() {
    this.add.image(240, 320, 'oranges')
  }
}

JSONP 源位于不同的服务器上,其结构如下:

/**/ typeof handleItems === 'function' && handleItems([
{"offerWeek":"kw17","id":"1028377","name":"Bananen","price":"1.79","url":"https://www.rewe.de/angebote/nationale-angebote/#1028377","image":"https://upload.wikimedia.org/wikipedia/commons/5/5d/Pl%C3%A1tanos_de_Canarias.JPG"},
{"offerWeek":"kw17","id":"2670547","name":"Big City Pizza","price":"1.99","url":"https://www.rewe.de/angebote/nationale-angebote/#2670547","image":"https://upload.wikimedia.org/wikipedia/commons/a/a5/Pizza_20.jpg"},
{"offerWeek":"kw17","id":"3663221","name":"Die Thüringer Bratwurst","price":"4.59","url":"https://www.rewe.de/angebote/nationale-angebote/#3663221","image":"https://upload.wikimedia.org/wikipedia/commons/9/91/Bratwurst_on_the_grill.jpg"},
{"offerWeek":"kw17","id":"3919250","name":"Orangen","price":"2.99","url":"https://www.rewe.de/angebote/nationale-angebote/#3919250","image":"https://upload.wikimedia.org/wikipedia/commons/4/43/Ambersweet_oranges.jpg"}]
);

如何访问产品名称和图像并在 Phaser 中显示它们?另外,在调用create()之前如何等待请求完成?所有建议都表示赞赏!

javascript jsonp phaser-framework

评论


答:

1赞 winner_joiner 4/21/2023 #1

可能有一个更好的解决方案,但我的第一个想法是:

  1. 创建一个全局变量,如下所示

     var globalItemsStore = { isLoaded: false, inGame: false,  items: []};
    
  2. 创建 JSONP 回调函数,如下所示

     function handleItems(loadedItems){
         globalItemsStore = {
             isLoaded: true,
             inGame: false, 
             items: loadedItems
         };
     }
    
  3. 现在在你的游戏方法的场景中,你可以检查完成的加载,像这样
    (或者替代只是使用全局变量)
    update

     ...
     update(){
         ...
         if(!globalItemsStore.inGame && globalItemsStore.isLoaded){
             // Do your thing ...
             globalItemsStore.inGame = true;
         }
     }
     ...
    

或者,如果你想在移相器中使用事件和发射器,这里有一个小例子:

document.body.style = 'margin:10px;';

var button = document.querySelector('#button');
const DEMO_ITEMS = [1,2,3,4,5,6];

button.addEventListener('click', () => handleItems(DEMO_ITEMS));

function handleItems (items){
    game.scene.scenes[0].events.emit('DATA-LOADED', items);
}

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 143,
    scene: {
        create
    },
    banner: false
}; 

function create () {
    this.add.text(10,10, 'Click the HTML Button to simulate,\nloading Data.')
        .setScale(1.5)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
        
    // you can use any string for the event Name
    this.events.on('DATA-LOADED', args => {
      console.info(args);
      this.add.text(10, 80, `Data loaded!\nItemCount: ${args.length}`)
        .setScale(1.5)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial', color: 'green'});
    });
}

var game = new Phaser.Game(config);
<button id="button" style="margin-bottom:5px;"> Simulate Load Data </button> <br>

<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>

只:

  1. 在方法中创建事件侦听器,使用链接到文档createthis.events.on(...);
  2. jsonp 回调函数中,调用该函数。文档链接scene.events.emit(...)

你只需要选择正确的场景。如果你只有一个,那就很容易了

如果您只想在加载数据后启动游戏,那么简单的解决方案是在函数中创建游戏。像这样的东西handleItems

    function handleItems(loadedItems){
       var game = new Phaser.Game(config)
       game._myLoadedItems = loadedItems;
    }

在 create 函数中,您可以获得如下数据:

   create(){
       console.info(this.game._myLoadedItems);
       ...
   }

评论

0赞 jurgenizer 4/21/2023
哇!!!非常感谢您全面准确的回答。我正在按照您的示例使用 Phaser 事件和发射器:)
0赞 winner_joiner 4/21/2023
感谢您的反馈,我很高兴我能提供帮助。如果它解决了您的问题,请考虑接受我的答案,并带有绿色复选标记。提前致谢。