3

I am trying to load data (including images) via a JSONP feed into Phaser 3.60.0. I know how to load image asset normally as per my GameScene.js code below:

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')
  }
}

The JSONP feed is located on a different server and is structured like this:

/**/ 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"}]
);

How do I access the product names and images and display them in Phaser? Also how do I wait for the request to finish before create() is called? All advice appreciated!

1 Answer 1

1

There is probably a better solution, but my first idea would be:

  1. create a global variabel, like this

     var globalItemsStore = { isLoaded: false, inGame: false,  items: []};
    
  2. create the jsonp callback function, like this

     function handleItems(loadedItems){
         globalItemsStore = {
             isLoaded: true,
             inGame: false, 
             items: loadedItems
         };
     }
    
  3. Now in your game in the update method of the scene, you can check for the finished load, like this
    (Or alternative just use the global variable)

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

OR if you want to use events and emitters in phaser, here is a small example:

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>

Just:

  1. create an event listener in the create method, with this.events.on(...); (link to the documentation)
  2. In the jsonp callback function, call the scene.events.emit(...) function. (link to the documentation)

You just have to select the correct scene. If you only have one it is easy

If you only want to start the game after loading the data, the easy solution would be to create the game in the handleItems function. Something like this

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

and in the create function you could get the data like this:

   create(){
       console.info(this.game._myLoadedItems);
       ...
   }
Sign up to request clarification or add additional context in comments.

2 Comments

Wow!!! Thank you so much for your comprehensive and accurate answer. I am using the Phaser events and emitters as per your example :)
Thank you for your feedback, I'm glad I could help. If it solved your problem, please consider accepting my answer with the green checkmark. Thanks in advance.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.