Phaser 3:更新 ajax 响应中的场景变量

Phaser 3: Updating scene variable inside ajax response

我正在尝试更新 ajax 请求的响应中的变量,以查看用户传递的令牌是否为真。

完整场景代码如下:

class InitScene extends Phaser.Scene{

    constructor(){
        super("InitScene")
    }

    preload(){
        this.Token = getParameterByName('Token')||1;
        let validateData ={
            Token:this.Token
        }
        this.correctToken=false;
        $.ajax({
            url: "validateTokenAPI",
            type: "POST",
            data: JSON.stringify(validateData),
            headers: {
                "Content-Type": "application/json"
            },
            success: function (response) {
                // response is a bool
                this.correctToken = response;
                console.log(this.correctToken);
            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log('error');
            }
        });
    }

    create(){

        let { width, height } = this.sys.game.canvas;
        this.add.text(width/2, height/2,"LOADING...", {font: "28px Arial", fill: "black"}).setOrigin(0.5);

        console.log(this.correctToken);
        if(this.correctToken){
            this.scene.start("NextScene");
        } 
    }

    update(){
        console.log(this.correctToken);
        if(this.correctToken){
            this.scene.start("NextScene");
        } 
    }
}



function getParameterByName(name, url = window.location.href) {
    name = name.replace(/[\[\]]/g, '\$&');
    var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

我试图在预加载函数中获取 ajax 的结果,然后在创建或更新中使用它。

函数getParameterByName只是plagiarized从url;

获取令牌

preload 函数最初将 this.correctToken 的值设置为 false,如果 ajax 响应为真,则将其设置为 true;

如果 Token 正确,创建和更新功能会将玩家移动到下一个场景(我都尝试过,因为我认为这可能是由于 ajax 的异步性质?)

this.correctToken 的值在创建和更新中始终打印为 false,但在 ajax 响应

中为真

这不起作用,因为我猜 ajax 是异步的,并且值是在响应 ID 返回之前在预加载中设置的??

我同样尝试将 ajax 放入创建中,然后在更新中使用它。

在函数中添加 ajax 然后返回响应也不起作用。

makeValidateAjax(Token){

    let validateData ={
        Token:Token
    }
    $.ajax({
        url: "validateTokenAPI",
        type: "POST",
        data: JSON.stringify(validateData),
        headers: {
            "Content-Type": "application/json"
        },
        success: function (response) {
            return response;
        },
        error: function(jqXHR, textStatus, errorThrown) {
            return false;
        }
    });
}

编辑 同样在 ajax 响应中调用 this.scene.start("NextScene"); 不起作用,因为场景未在 ajax...

中定义

编辑 2

#correctToken;

constructor(){
    super("InitScene")
    this.#correctToken=false;
}

还在构造函数中定义变量 returns 当我在 ajax 响应中更改它时出错

Uncaught TypeError: Cannot write private member #correctToken to an object whose class did not declare it

考虑将 EventEmitter. It could be something along these lines 与单例模式结合使用:

// eventDispatcher.js
export default class EventDispatcher extends Phaser.Events.EventEmitter {
  constructor() {
    super();
  }
  static getInstance() {
    if (instance === null) {
        instance = new EventDispatcher();
    }
    return instance;
  }
}

    // InitScene's preload

    this.emitter = EventDispatcher.getInstance();

    // use fat arrow functions to preserve the .this in the ajax's callback
    [...]
    success: (response) => {
      // response is a bool
      this.correctToken = response;
      console.log(this.correctToken);
      this.emitter.emit('CORRECT_TOKEN', this.correctToken);
    },
    [...]

    // create
    this.emitter.on('CORRECT_TOKEN', (token) => {
        this.scene.start("NextScene");
    });

作为替代方案,如果您愿意安装 Rex 的插件之一(它们都非常棒),我会选择 Await loader

我正在模拟一些未经测试的主要代码(您需要按照文档页面所述进行设置)。 Full standalone example on github

const callback = function(successCallback, failureCallback) {
  $.ajax({
    url: "validateTokenAPI",
    type: "POST",
    data: JSON.stringify(validateData),
    headers: {
      "Content-Type": "application/json"
    },
    success: (response) => {
      // response is a bool
      this.correctToken = response;
      console.log(this.correctToken);
      successCallback(); 
    },
    error: (jqXHR, textStatus, errorThrown) => {
      console.log('error');
      failureCallback();
    }
  });
}
this.load.rexAwait(callback);