axiosphaser-frameworkphaserjs

Phaser.js Axios Timing Issue When Changing Scenes


Is there a way to make an axios get call inside my Phaser 3 code, and then load a new scene with the response data? At the moment, I am having a kind of timing issue where I think the second scene gets loaded before the axios call can return a response? Any help would be greatly appreciated. Here is my code. First, inside my SelectDifficultyScene js file:

preload()
{
    this.fetchSudoku();
    
    // this.scene.start(GameScene, this.sudoku);
}

async fetchSudoku()
{
    self = this;
    
    console.log("Select Difficulty Scene");

    try
    {
        const response = await axios.get('api/fetch-sudoku');
        console.log("Select Difficulty Scene", self.sudoku);
        self.setSudoku(response.data);
        self.loadGameScene();
        // const gameScene = new GameScene();
    } catch(error) {
        console.log(error);
    }
}

setSudoku(sudoku)
{
    this.sudoku.unsolvedSudoku = sudoku.unsolvedSudoku;
    this.sudoku.solvedSudoku = sudoku.solvedSudoku;
    this.sudoku.difficultyLevel = "Easy";
}

loadGameScene()
{
    this.scene.start('GameScene', this.sudoku);
}

Then, inside my GameScene file:

init(sudoku)
{
    // console.log(sudoku);
    this.setSudokuNumbers(sudoku);
}

setSudokuNumbers(sudoku)
{
    let unsolvedCount = 0;
    let solvedCount = 0;
    for(let x = 0; x < 9; x++)
    {
        for(let y = 0; y < 9; y++)
        {
            this.sudokuGridUnsolved[x][y] = sudoku.unsolvedSudoku[unsolvedCount];
            this.sudokuGridSolved[x][y] = sudoku.solvedSudoku[solvedCount];
            unsolvedCount++;
            solvedCount++;
        }
    }
    
    // console.log(sudoku, this.sudokuGrid);
}

When I load both scenes inside my game config file, GameScene gets loaded and I see no response data inside my dev tools. When I remove GameScene from game config and try again, I get the correct response data loaded?


Solution

  • I think the issue is the order in which you loading the scenes in your config, but wihtout seeing it I'm just guessing.
    The order matters in the array, in the first code snippet GameScene is loaded and displayed first. SelectDifficultyScene is loaded but not started/displayed.

    const config = {
        type: Phaser.AUTO,
        ...
        scene: [ GameScene, SelectDifficultyScene ]
    };
    

    Switching the order of the scenes should solve your problem, if I understud you setup correct.

    const config = {
        type: Phaser.AUTO,
        ...
        scene: [ SelectDifficultyScene, GameScene ]
    };
    

    Update
    (small working demo)

    document.body.style = 'margin:0;';
    
    class FirstScene extends Phaser.Scene {
        constructor(){
            super('FirstScene');
        }
        
        create(){
            let label = this.add.text(10,10, 'FirstScene\n... please wait')
                .setScale(1.5)
                .setOrigin(0)
                .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
            
            setTimeout( _ =>
              axios.get('https://jsonplaceholder.typicode.com/posts/1')
                .then((response) => {
                  this.scene.start('SecondScene', response.data);
                })
                .catch(function (error) {
                  label.setText(` First Scene\nError: ${error}`);
                }), 
            2000);
        }
    }
    
    class SecondScene extends Phaser.Scene {
        constructor(){
            super('SecondScene');
            console.info(this);
        }
        
        create(data){
        
            let label = this.add.text(10,10, 'SecondScene')
                .setScale(1.5)
                .setOrigin(0)
                .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
                
            let dataLabel = this.add.text(10, 40, JSON.stringify(data))
                .setOrigin(0)
                .setWordWrapWidth(300)
                .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});   
        }
    }
    
    var config = {
        type: Phaser.AUTO,
        width: 536,
        height: 183,
        scene: [FirstScene, SecondScene],
    }; 
    
    new Phaser.Game(config);
    <script src="//cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js"></script>
    <script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>