0
\$\begingroup\$

I am looking for an equation for predicting the future position of a moving arcade physics body in Phaser 3. The body has drag applied and isDamping set to true. Phaser applies the drag using the following run on each update (showing x axis only but same applies to y).

//  Damping based deceleration
dragX = Math.pow(dragX, delta);

velocityX *= dragX;

Given the above, how would I write a kinetic equation to predict the future position?

I am currently using the method below, where I am iterating over frames to calculate the position accumulatively. But this is inefficient and inelegant so would prefer a solution which estimates the position without any looping.

public futurePosition(timeInSeconds: number): Phaser.Math.Vector2 {
  const DELTA = 1 / 60; // Assume we are running at 60fps
  const DRAG = 0.3; // Drag value
  const position = this.position.clone(); // Current position of body
  const velocity = this.body.velocity.clone(); // Current velocity

  // Inefficiently looping through frames
  for (let i = 0; i < timeInSeconds / (DELTA * 1000); i++) {
    velocity.x *= Math.pow(DRAG, DELTA);
    velocity.y *= Math.pow(DRAG, DELTA);
    position.x += velocity.x * DELTA;
    position.y += velocity.y * DELTA;
  }

  return position;
}

Any help appreciated. Thanks.

\$\endgroup\$
4
  • \$\begingroup\$ I believe that it should be possible to solve this using integral calculus. Unfortunately that's not my strong suit. \$\endgroup\$ – Philipp Apr 8 at 13:13
  • \$\begingroup\$ Okay thanks Philipp. I will try and bend my mind round some calculus. \$\endgroup\$ – Calabi Apr 8 at 13:45
  • \$\begingroup\$ I've shared solutions for this here and here which might be useful to you. \$\endgroup\$ – DMGregory Apr 8 at 15:32
  • \$\begingroup\$ I'll have a read @DMGregory, thanks. \$\endgroup\$ – Calabi Apr 8 at 17:44
0
\$\begingroup\$

Solved with a geometric progression.

public futurePosition(timeInSeconds: number): Phaser.Math.Vector2 {
  const fps = 60;
  const drag = Math.pow(0.3, 1 / fps);
  const x = ((this.body.velocity.x / fps) * (1 - Math.pow(drag, timeInSeconds * fps))) / (1 - drag);
  const y = ((this.body.velocity.y / fps) * (1 - Math.pow(drag, timeInSeconds * fps))) / (1 - drag);

  return new Phaser.Math.Vector2(this.position.x + x,  this.position.y + y);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.