Fix ladder entry/exit logic to handle top entry and prevent premature exits
This commit is contained in:
parent
a8262f4bbf
commit
be160ed954
|
|
@ -14,6 +14,7 @@ export default class Player {
|
||||||
this.lives = 3;
|
this.lives = 3;
|
||||||
this.onLadder = false;
|
this.onLadder = false;
|
||||||
this.atLadderTop = false;
|
this.atLadderTop = false;
|
||||||
|
this._enteredFromTop = false;
|
||||||
|
|
||||||
// Create physics sprite
|
// Create physics sprite
|
||||||
this._sprite = scene.physics.add.sprite(x, y, 'player', 0);
|
this._sprite = scene.physics.add.sprite(x, y, 'player', 0);
|
||||||
|
|
@ -51,11 +52,13 @@ export default class Player {
|
||||||
_handleLadder() {
|
_handleLadder() {
|
||||||
const sprite = this._sprite;
|
const sprite = this._sprite;
|
||||||
const cursors = this._cursors;
|
const cursors = this._cursors;
|
||||||
|
const body = sprite.body;
|
||||||
|
|
||||||
// Tile at player center (for body-of-ladder detection)
|
// Tile at player center (for body-of-ladder detection)
|
||||||
const centerTile = this._laddersLayer.getTileAtWorldXY(sprite.x, sprite.y);
|
const centerTile = this._laddersLayer.getTileAtWorldXY(sprite.x, sprite.y);
|
||||||
// Tile at player feet (for ladder-top detection)
|
// Tile just below body bottom (body bottom = sprite.y + 120; +2 puts us inside
|
||||||
const feetTile = this._laddersLayer.getTileAtWorldXY(sprite.x, sprite.y + 116);
|
// the tile when standing on it, since physics places body bottom at tile top)
|
||||||
|
const feetTile = this._laddersLayer.getTileAtWorldXY(sprite.x, sprite.y + 122);
|
||||||
|
|
||||||
const centerIsLadder = centerTile && TilePropertyHelper.isLadder(centerTile.index);
|
const centerIsLadder = centerTile && TilePropertyHelper.isLadder(centerTile.index);
|
||||||
const feetIsLadderTop = feetTile && TilePropertyHelper.isLadderTop(feetTile.index);
|
const feetIsLadderTop = feetTile && TilePropertyHelper.isLadderTop(feetTile.index);
|
||||||
|
|
@ -79,8 +82,16 @@ export default class Player {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit ladder if center is no longer over a ladder tile
|
// Once the center reaches a ladder tile we are fully on the ladder
|
||||||
if (!centerIsLadder) {
|
if (centerIsLadder) {
|
||||||
|
this._enteredFromTop = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit if center is no longer over a ladder tile.
|
||||||
|
// Exception: when we entered from the top the center starts above the ladder;
|
||||||
|
// suppress the exit until the player descends into the rungs, or until
|
||||||
|
// they press up (changing their mind).
|
||||||
|
if (!centerIsLadder && (!this._enteredFromTop || cursors.up.isDown)) {
|
||||||
this._exitLadder();
|
this._exitLadder();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -92,12 +103,21 @@ export default class Player {
|
||||||
sprite.body.setVelocityX(0);
|
sprite.body.setVelocityX(0);
|
||||||
// Snap horizontally to ladder center
|
// Snap horizontally to ladder center
|
||||||
sprite.x = centerTile.pixelX + 64;
|
sprite.x = centerTile.pixelX + 64;
|
||||||
|
// Enter from the top: standing on the top rung tile, pressing down
|
||||||
|
} else if (feetIsLadderTop && cursors.down.isDown && body.blocked.down) {
|
||||||
|
this._enteredFromTop = true;
|
||||||
|
this.onLadder = true;
|
||||||
|
sprite.body.setGravityY(-800);
|
||||||
|
sprite.body.setVelocityY(200);
|
||||||
|
sprite.body.setVelocityX(0);
|
||||||
|
sprite.x = feetTile.pixelX + 64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_exitLadder() {
|
_exitLadder() {
|
||||||
this.onLadder = false;
|
this.onLadder = false;
|
||||||
|
this._enteredFromTop = false;
|
||||||
this._sprite.body.setGravityY(0); // Remove local gravity override; world gravity resumes
|
this._sprite.body.setGravityY(0); // Remove local gravity override; world gravity resumes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue