How do I match one object to the location of another moving object?

tl;dr - Is there a way to position something AFTER physics calculations have updated everything’s positions?

There are times when I want to position a game object at a precise position relative to another game object. Let’s call the object whose position I want to match “target,” and the object I want to position relative to the target “follower.” This is pretty straightforward when the target is stationary, but if it has a velocity, it seems that Phaser positions the follower at the correct position relative to the target, then updates the target’s position based on its velocity.

The result is that when the frame is drawn, the follower lags a bit behind the target when the target is moving. Note that this isn’t an issue when I’m positioning both elements myself, since there’s no velocity calculation taking place afterward.

Screen Shot 2021-09-28 at 1.26.43 PM Screen Shot 2021-09-28 at 1.27.13 PM

On the left, the tank (my target) is stationary, and the muzzle flash (my follower) is positioned where I want it.
On the right, the target is moving to the left, and my muzzle flash is being rendered where it USED to be before taking velocity into account. It’s a small difference here, but it’s very noticeable the higher the speed gets.

Here are some things I’ve tried / learned:

  1. Containers:
    As controversial as they seem to be, I’m using a container to position the parts of my tank relative to the tank’s hull. The tank tracks and the cannon are separate game objects and can animate and move freely relative to the container. When I give the container a velocity, it positions all its children accordingly. This would work for my muzzle flash, but not for my bullet! Once the bullet fires, it needs to have its own trajectory, I can’t have its x velocity tied to my tank!

  2. Manually calculate the target’s updated position
    Using the “deltaTime” argument from the scene’s update function, I can position my bullet at the tank’s position PLUS the tank’s velocity x deltaTime:
    bullet.setX( tank.x + tank.body.velocity.x * deltaTime );
    This works! But it’s annoying. I have to pass deltaTime around to the function I need it in. Is there a more global way to access deltaTime (I believe Arcade Physics has a fixed timestep, so this could potentially be a constant)? And what if the object doesn’t have a velocity, but is set as a Path follower, or is moving in some other Phaser-calculated way?

Is there a more Phaser-standard way to handle positioning relative to moving bodies? Like a method for positioning something AFTER physics/Phaser calculations have taken place and updated everything’s position?

Either read the physics body coordinates in scene update() or read the game object coordinates in a scene postupdate event handler.

Thank you!! I didn’t know that the body’s properties took physics updates into account. Plus the “on postupdate” event is just what I was originally looking for and I’m sure will come in handy at some point. I was looking for a method that hooked into the lifecycle at that point, I should have thought of looking for an event that emits during the lifecycle, that makes sense!

Added bonus, I didn’t even know those Phaser.Display positioning methods (Align / Bounds) existed, time for a refactor to cut out a lot of boring calculations!

As a quick recap, for those who don’t want to follow the link, here’s how these solutions pertain to my example:

// Use EITHER:
// (1) Read sprite position in 'postupdate' or
// (2) Read body position in update()

// (1) in create()
this.events.on("postupdate", function () {
  // Aligns bottom-center of muzzle flash to top-center of cannon
  Phaser.Display.Align.To.TopCenter(follower, target);
});

// (2) in update()
Phaser.Display.Bounds.SetCenterX(follower, target.body.center.x);
Phaser.Display.Bounds.SetBottom(follower, target.body.top);

This helps me a lot too. Thank you!