在移相器 3 中创建一个在屏幕上移动的框

Creating a box that moves accross the screen in phaser 3

这是我的代码,我之前发过这个问题,但不是很清楚所以我重新发布 问题出在 createBox() 函数中(或者当它被调用时)。该框在游戏开始时创建一次,但无法通过 s 的按键再次创建。我想帮助使盒子在按下 s 并在屏幕上移动时产生。球员应该能够跳出禁区。

const config = {
  type: Phaser.AUTO,
  width: 1905,
  height: 1000,
  backgroundColor: '#000',
  physics: {
    default: 'arcade',
    arcade: {
      gravity: {
        y: 300
      },
      debug: false
    }
  },
  scene: {
    preload: preload,
    create: create,
    update: update
  }
};
const game = new Phaser.Game(config);
var player
var wait = 1
var boxes
function preload() {
  this.load.image('player', 'assets/repl.png');
  this.load.image('ocean', 'assets/water.png');
  this.load.image('background', 'assets/background.png');
  this.load.image('box', 'assets/box.png');
  this.load.image('platform1', 'assets/platform1.png');
  this.load.image('platform2', 'assets/platform2.png');
  this.load.image('platform3', 'assets/platform3.png');
  this.load.image('platform4', 'assets/platform4.png');
}

function create() {
  this.add.image(950, 450, 'background').setScale(1.4);
  this.w = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W)
  this.a = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A)
  this.s = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S)
  this.d = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D)
  waters = this.physics.add.staticGroup();
  waters.create(952, 958, 'ocean').setScale(1.4).refreshBody();

  platform1s = this.physics.add.staticGroup();
  platform1s.create(952, 858, 'platform1').setScale(0.5).refreshBody();

  player = this.physics.add.sprite(1000, 500, 'player').setScale(0.05);
  player.setCollideWorldBounds(true);

  box = this.physics.add.group();
  boxes = box.create(0, 900, 'box').setScale(0.1);
  boxes.body.setAllowGravity(false);
  boxes.setVelocityX(200)

  this.physics.add.collider(player, waters, hitWater, null, this);
  this.physics.add.collider(player, platform1s);
  // this.physics.add.collider(player, platform2s);
  // this.physics.add.collider(player, platform3s);
  // this.physics.add.collider(player, platform4s);
  this.physics.add.collider(player, boxes);
}

function update() {
  let cursors = this.input.keyboard.createCursorKeys();
  if (this.a.isDown) {
    player.setVelocityX(-300)
  } else if (this.d.isDown) {
    player.setVelocityX(300)
  } else {
    player.setVelocityX(0)
  }
  if (this.w.isDown && player.body.touching.down) {
    player.setVelocityY(-400)
  }
  if (this.s.isDown) {
    if (wait = 1) {
      createBox()
    }
  }
}
function createBox() {
  box = this.physics.add.group();
  boxes = box.create(0, 900, 'box').setScale(0.1);
  boxes.body.setAllowGravity(false);
  boxes.setVelocityX(200)
  this.physics.add.collider(player, boxes);
  this.time.delayedCall(1000, delayer, null, this);
}
function hitWater() {
  this.physics.pause();
  player.setTint(0xff0000);
  this.time.delayedCall(3000, restart, null, this);
}
function restart() {
  this.scene.stop();
  this.scene.start();
}
function delayer() {
  wait = 1
}

最快的解决方法是bind场景到update函数中的createBox函数:

  ...
  if (this.s.isDown) {
    if (wait == 1) {
      createBox.bind(this)(); // binding the context
    }
  }
  ...

看起来不太好但很管用。

bind is a javascript function that set's the this object of function, here is the documenation
createBox.bind(this) creates a new function where the this inside the function, is the passed parameter.

在大多数 Javascript 事件中,例如按下键或鼠标或...这个对象是 window 对象,这就是为什么您需要设置上下文的原因。

备选方案: 您可以将 scene 作为参数传递给函数,但为此您必须稍微更改 createBox 函数更多:

...
if (this.s.isDown) {
    if (wait == 1) {
        createBox(this)
    }
}
...

function createBox(scene) {
    box = scene.physics.add.group();
    boxes = box.create(0, 900, 'box').setScale(0.1);
    boxes.body.setAllowGravity(false);
    boxes.setVelocityX(200)
    scene.physics.add.collider(player, boxes);
    scene.time.delayedCall(1000, delayer, null, scene);
}