Riding moving Platforms?

Hi Everyone,

I’m working on the game with tweened moving plaftorms, but my player character won’t “stick” to the platform on the X direction.

ezgif-4-2dcec4486f99

Both the player and platform bodies have an X friction of 1.

For reference, this is the platform physics group:

const movingPlatforms = scene.physics.add.group({
    allowGravity: false,
    immovable: true,
  });

The player is has immovable set to false. I’m wondering: is there a simple setting I’m missing, or will I need to go the route of grabbing the platform’s velocity and adding it to the player object’s?

Thanks!!

1 Like

Friction won’t work with tweened sprites. :slightly_frowning_face:

You can maybe fake it somehow in a collision callback.

Thanks @samme!

Hmm… that’s a tricky one! Right, using the collision callback is what I’m looking at now. I think I’ll try offsetting the position of the player by the amount of the platform’s velocity.

(I’ve noticed that the tweened sprites have 0 x/y velocities. Is there a way of obtaining the velocity of tweened sprites, or would I need to calculate that manually?

Yes, you have to calculate the tweened position delta yourself, perhaps in tween onUpdate.

@samme, Thanks! - I will try that!

Managed to get it working, thanks to your advice, @samme!

I calculated the platform’s velocity in the tween’s onUpdate, like this:

    this.tweens.timeline({
              targets: platform,
              ease,
              yoyo,
              loop: -1,
              tweens,
              onUpdate: () => {
                platform.vx = platform.body.position.x - platform.previousX;
                platform.vy = platform.body.position.y - platform.previousY;
                platform.previousX = platform.body.position.x; 
                platform.previousY = platform.body.position.y; 
              }
            }); 

Then set up the collision callback to tell the player sprite that the platform collision was occurring and to pass it a reference to the platform:

const collisionMovingPlatform = (sprite, platform) => {
      if (platform.body.touching.up && sprite.body.touching.down) {
        sprite.isOnPlatform = true;
        sprite.currentPlatform = platform;      
      }
    };
    //Only allow collisions from top
    const isCollisionFromTop = (sprite, platform) => {
      return platform.body.y > sprite.body.y;
    };

    this.physics.add.collider(
      sprite,
      movingPlatforms,
      collisionMovingPlatform,
      isCollisionFromTop,
      scene
    );

Then in the player’s update method, applied the platform’s velocity to the player’s position.

if (this.isOnPlatform && this.currentPlatform) {
      this.body.position.x += this.currentPlatform.vx;
      this.body.position.y += this.currentPlatform.vy;

      this.isOnPlatform = false;
      this.currentPlatform = null;
    }

Works like a charm!

ezgif-4-fa06f4e080e5

6 Likes

Here is a similar solution, setting a velocity during the tween. It uses PathFollower#pathDelta, which would be much like your platform.vx, platform.vy.

2 Likes