You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Phaser.js场景切换时Axios请求时序问题求解

解决Phaser 3中Axios请求后加载场景的时序问题

核心问题

你遇到的问题根源是:Phaser游戏配置中声明的所有场景会被自动初始化,哪怕你没手动调用scene.start。所以GameScene的init方法会在Axios异步请求完成前就执行,自然拿不到返回的数据。


方案1:动态注册GameScene(推荐)

不在游戏配置里提前注册GameScene,等Axios请求成功后再动态注册并启动它,从根源避免时序冲突。

修改SelectDifficultyScene.js的代码:

preload() {
    this.fetchSudoku();
}

async fetchSudoku() {
    console.log("Select Difficulty Scene");
    try {
        const response = await axios.get('api/fetch-sudoku');
        this.setSudoku(response.data);
        // 动态注册并启动GameScene,第三个参数true表示立即启动
        this.scene.add('GameScene', GameScene, true, this.sudoku);
    } catch(error) {
        console.log(error);
    }
}

setSudoku(sudoku) {
    // 先初始化sudoku对象,避免undefined报错
    this.sudoku = {
        unsolvedSudoku: sudoku.unsolvedSudoku,
        solvedSudoku: sudoku.solvedSudoku,
        difficultyLevel: "Easy"
    };
}

游戏配置中只保留SelectDifficultyScene:

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    // 仅注册初始场景
    scene: [SelectDifficultyScene]
    // 其他配置项...
};

方案2:让GameScene等待数据就绪

如果必须在配置里注册GameScene,可以给GameScene添加事件监听,等待数据就绪后再处理:

修改GameScene.js的代码:

init(sudoku) {
    // 如果初始化时没有拿到数据,监听自定义事件等待数据
    if (!sudoku) {
        this.events.on('sudoku-ready', (data) => {
            this.setSudokuNumbers(data);
        });
        return;
    }
    // 拿到数据直接处理
    this.setSudokuNumbers(sudoku);
}

setSudokuNumbers(sudoku) {
    let count = 0;
    // 合并重复的计数变量,简化代码
    for(let x = 0; x < 9; x++) {
        for(let y = 0; y < 9; y++) {
            this.sudokuGridUnsolved[x][y] = sudoku.unsolvedSudoku[count];
            this.sudokuGridSolved[x][y] = sudoku.solvedSudoku[count];
            count++;
        }
    }
}

修改SelectDifficultyScene.js的loadGameScene方法:

loadGameScene() {
    const gameScene = this.scene.get('GameScene');
    if (gameScene) {
        // 触发自定义事件传递数据
        gameScene.events.emit('sudoku-ready', this.sudoku);
    } else {
        this.scene.start('GameScene', this.sudoku);
    }
}

额外修复点

  1. 原代码中setSudoku方法直接给this.sudoku赋值属性,但如果this.sudoku未提前初始化会报错,方案1中已通过直接创建对象解决。
  2. 原fetchSudoku里的self = this存在全局作用域污染风险,直接使用this即可(async函数中this指向当前场景实例)。

内容的提问来源于stack exchange,提问作者summer9844

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 16:03:19