如何让2D游戏角色随移动平台同步移动?
实现角色随Tween移动平台同步移动的方案
我在2D游戏中做了一个角色和通过Tween实现左右移动的平台,平台是用TiledMapEditor创建的对象并赋予纹理生成的。现在想实现角色站在平台上时能跟着一起移动,试过多种方法都没成功,求解决办法。
现有代码
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 { } }
生成移动平台的代码(已正常工作)
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); }); }
当前碰撞器代码
this.physics.add.collider(this.player, this.movements, () => {});
解决方案
核心问题是:Tween直接修改平台的x属性,但Phaser物理系统不会自动把平台的位移同步给站在上面的角色,需要手动处理位移同步。
1. 修改MovementPlatform类,记录位移增量
给平台添加属性记录上一帧的位置,在update方法中计算每一帧的位移差,同时同步物理碰撞体的位置:
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; private prevX: number; // 新增:记录上一帧的x坐标 constructor(props: ActorProps) { super(props); this.scene.physics.add.existing(this); this.body.setAllowGravity(false); this.body.immovable = true; this.startX = this.x; this.prevX = this.x; // 初始化上一帧坐标 this.move(); } update(...args: any[]): void { // 计算当前帧的位移差,同步物理碰撞体位置 const deltaX = this.x - this.prevX; this.body.x += deltaX; this.prevX = this.x; // 更新上一帧坐标 } die(): void { } move(): void { this.scene.tweens.add({ targets: this, x: this.startX + 200, duration: 1000, yoyo: true, repeat: -1, }); } collect(...props: any[]): void { } }
2. 修改碰撞器回调,同步角色位移
在碰撞回调中判断角色是否站在平台上方,只有满足条件时才把平台的位移增量同步给角色:
this.physics.add.collider(this.player, this.movements, (player, platform) => { const movementPlatform = platform as MovementPlatform; // 确保角色是站在平台顶部(避免侧面碰撞触发同步) if (player.body.touching.down && movementPlatform.body.touching.up) { const deltaX = movementPlatform.x - movementPlatform.prevX; player.x += deltaX; // 如果角色使用物理系统控制,也可以同步body的位置 player.body.x += deltaX; } });
3. 关键说明
- 保持平台的
immovable: true,避免角色推动平台; - 同步
body.x是为了让物理碰撞体和视觉对象位置一致,防止碰撞判断出现偏移; - 碰撞条件判断确保只有角色站在平台上时才同步位移,避免误触发。
内容的提问来源于stack exchange,提问作者yunusemre agdin
相关产品推荐
相关产品推荐

