yunusemre agdin
yunusemre agdin

Reputation: 81

How to make character move along with the platform?

in my 2D game I have 1 character and a platform that moves left and right with tweens. I created this platform as an object in tiledmapeditor and it spawns by giving texture. When my character comes on this platform, I want it to move with the platform. How do I do this.

This is my MovementPlatform.ts ;

    import {
  ActorProps,
  ICollectable,
  IDieable,
  IMoveable,
} from "@games/common/interfaces";
import { Actor } from "@games/common/objects";

export default class MovementPlatform
  extends Actor
  implements IMoveable, IDieable, ICollectable {
  declare body: Phaser.Physics.Arcade.Body;
  declare startX;
  constructor(props: ActorProps) {
    super(props);
    this.scene.physics.add.existing(this);
    this.body.setAllowGravity(false);
    this.body.immovable = true;
    this.startX = this.x;

    this.move();
  }

  update(...args: any[]): void { }

  die(): void { }

  move(): void {
    this.scene.tweens.add({
      targets: this,
      x: this.startX + 200,
      duration: 1000,
      yoyo: true,
      repeat: -1,
    });
  }

  collect(...props: any[]): void { }
}

This is where spawning movementPlatform from tiledmapeditör(this is already working correctly)

    private spawnMovementPlatform() {
  const movementPlatformTiles = getObjectsByType(
    "movementPlatform",
    this.map
  );

  movementPlatformTiles.forEach((el: Phaser.Tilemaps.Tile, i: number) => {
    const movementplatform = new MovementPlatform({
      key: `movementPlatform-${this.movements.length}`,
      scene: this,
      texture: "movementPlatform",
      x: el.x,
      y: el.y + 200,
    }).setDepth(3);

    this.movements.push(movementplatform);
  });
}

and I don't know if I need to check my collider and do it this way here or if I need to process in movementPaltform.ts. I tried a lot of things but it didn't work.

this.physics.add.collider(this.player, this.movements, () => {});

Upvotes: 2

Views: 118

Answers (2)

Secret Laboratory
Secret Laboratory

Reputation: 36

Dunno if you ever figured this out, but i'm playing around with Phaser and had the same problem with my little cat dude riding on horizontal platforms that are moved using tweens...

easiest way i found to get it to work,

 // in my class i have a reference to this.player, and el is referring to the current elevator i'm creating in a loop / assigning a tween

 this.tweens.add({
          targets: el,
          repeat: -1,
          x: elevator.maxX,
          duration: 10000 * elevator.speed,
          yoyo: true,
          // THIS IS THE RELEVANT PART FOR THE ANSWER
          onUpdate: (_tween, target) => {
            if (this.player?.body?.touching.down && target.body.touching.up) {
              this.player.x += target.body.deltaX() * 0.5
            }
          },
        })

by adding the onUpdate method to your tween, you can add the deltaX of the tween to the player's X position...i also had to multiply mine by the camera zoom value, but this seems to work ok for the basic gist of getting my character to ride on a platform moved via tweens

Upvotes: 0

winner_joiner
winner_joiner

Reputation: 14795

I'm not 100% sure what your code does, or what you have tried, but based on the mentioned details. I must assume, you would only need to call the move function on a collision (I would add a property isMoving to the class MovementPlatform just to be on the save side)

So basically:

this.physics.add.collider(this.player, this.movements, (player: any, platform:any) => {
    if(!platform.isMoving){
        platform.isMoving = true;
        platform.move();  
    }
});

Update:
The Problem is I didn't see you are moving the x and y position of the platform, if you use the physics functions like setVelocity, the "sticky" feature should work.

Short example:
Left side platform, the position is altered with a tween, similar to your code.
On the right side, I'm using the velocity function to move the platform (this works).

document.body.style = 'margin:0;';

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 183,
    physics: {
        default: 'arcade',
        arcade: {            
            gravity:{ y: 100 },
            debug: true
        }
    },
    scene: {
        create,
        update,
    },
    banner: false
}; 

function create () {
    this.add.text(10,10, 'Left move position, Right using physics')
        .setScale(1.5)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});

    let p1 = this.physics.add.existing(this.add.rectangle(200, 20, 10, 10, 0xff0000));
    
     let p2 = this.physics.add.existing(this.add.rectangle(400, 20, 10, 10, 0xff0000));
     let floor1StartX = 200;
     let floor1 = this.physics.add.existing(this.add.rectangle(floor1StartX, 80, 100, 10, 0x0000ff));
     floor1.body.setAllowGravity(false);
     floor1.body.setImmovable(true);     

     let floor2 = this.physics.add.existing(this.add.rectangle(400, 80, 100, 10, 0x0000ff))
     floor2.body.setAllowGravity(false);
     floor2.body.setImmovable(true);
     
     this.floor2 = floor2;

     this.physics.add.collider(p1, floor1);
     this.physics.add.collider(p2, floor2);
     
     this.tweens.add({
      targets: floor1,
      x: floor1StartX + 50,
      duration: 1000,
      yoyo: true,
      repeat: -1,
    });
}

function update(){
    if (this.floor2.x >= 400)
    {
        this.floor2.body.setVelocityX(-50);
    }
    else if (this.floor2.x <= 350)
    {
        this.floor2.body.setVelocityX(50);
    }
}

new Phaser.Game(config);
console.clear();
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>

Upvotes: 0

Related Questions