Reputation: 81
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
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
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