How do I add an object next to a moving object in Phaser?

Viewed 133

In the snippet below, I place two red squares next to each other. You can see there is no gap between them.

If I try to do the same thing with moving objects, there is a slight gap. What's the right way to do this?

GIF of behavior desribed above: Two stationary red squares next to each other, and two moving yellow squares with a slight gap in between them.

<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.min.js"></script>
  </head>
  <body>
    <script>
    var config = {
      type: Phaser.AUTO,
      width: 800,
      height: 600,
      physics: { default: 'arcade' },
      scene: { create: create, update: update },
    };

    var game = new Phaser.Game(config);
    var red, red2, yellow, yellow2;
    const velocity = -300;

    function create() {
      red = this.add.rectangle(400, 200, 100, 100, 0xff0000).setOrigin(0, 0);
      red2 = this.add.rectangle(red.x + 100, 250, 100, 100, 0xff6666).setOrigin(0, 0);

      yellow = this.add.rectangle(400, 400, 100, 100, 0xffff00).setOrigin(0, 0);
      this.physics.add.existing(yellow);
      yellow.body.velocity.x = velocity;
    }

    function update() {
      if (yellow.x < 200 && !yellow2) {
        yellow2 = this.add.rectangle(yellow.x + 100, 450, 100, 100, 0xffff66).setOrigin(0, 0);
        this.physics.add.existing(yellow2);
        yellow2.body.velocity.x = velocity;
      }
      if (yellow.x < -200) {
        this.scene.restart();
        yellow2 = undefined;
      }
    }
    </script>
  </body>
</html>
2 Answers

A easy way out is to use the Phaser function: Phaser.Display.Align.To.RightCenter and the event: postupdate.

You then just have to calculate the offset between the objects and add pass it into the function. ( documentation to the Align function). this is based on this solution: phaser forum

canvas{
transform: translate(-40%, -40%) scale(.3);
}
<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.min.js"></script>
  </head>
  <body style="overflow:hidden">
    <script>
    var config = {
      type: Phaser.AUTO,
      width: 800,
      height: 600,
      physics: { default: 'arcade' },
      scene: { create: create, update: update },
    };

    var game = new Phaser.Game(config);
    var red, red2, yellow, yellow2;
    const velocity = -300;

    var yOffSet = 0;

    function create() {
      red = this.add.rectangle(400, 200, 100, 100, 0xff0000).setOrigin(0, 0);
      red2 = this.add.rectangle(red.x + 100, 250, 100, 100, 0xff6666).setOrigin(0, 0);

      yellow = this.add.rectangle(400, 400, 100, 100, 0xffff00).setOrigin(0, 0);
      this.physics.add.existing(yellow);
      yellow.body.velocity.x = velocity;    
      
      this.events.on("postupdate", function () {
            if (yellow  && yellow2) {

                Phaser.Display.Align.To.RightCenter(yellow2, yellow, 0, yOffSet);
            }
        });
    }



    function update(time, delta) {

      if (yellow.x < 200 && !yellow2) {

        yellow2 = this.add.rectangle(yellow.x + 100, 450, 100, 100, 0xffff66).setOrigin(0, 0);
        this.physics.add.existing(yellow2);
        yellow2.body.velocity.x = velocity;
        yOffSet =   yellow2.y - yellow.y
      }
      if (yellow.x < -200) {
        this.scene.restart();
        yellow2 = undefined
      }
    }
    </script>
  </body>
</html>

Alternativly you could, calculate the x position more exact, but it is no easy since, the update function is not called in the same time interval. This could cause minor overlap or splitting.

// deltaTime being the the second paramenter of the update function
yellow2 = this.add.rectangle(yellow.x + 100 + (velocity * deltaTime), 450, 100, 100, 0xff0000).setOrigin(0, 0); 

Or even easier, you could simply set the x in the postUpdate event (without Align)

this.events.on("postupdate", function () {
    if ( yellow2) {
        yellow2.x =yellow.x + 100;
    }
});
Related