From b528b4fe65fc0510d497b7ee844a0976af7f0539 Mon Sep 17 00:00:00 2001 From: Admin Date: Mon, 21 Sep 2026 23:07:38 +0000 Subject: [PATCH] Smooth character drag follow behind touch --- src/main.js | 70 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/src/main.js b/src/main.js index d01b06c..163a20b 100644 --- a/src/main.js +++ b/src/main.js @@ -43,6 +43,8 @@ const HOUSE_BOUNDS = { } const STAIRS_X = 675 +const PLAYER_DRAG_FOLLOW = 0.18 +const PLAYER_DRAG_OFFSET_Y = 42 const PLAYER_IDLE_CROPS = [ { x: 145, y: 12, w: 199, h: 310 }, { x: 344, y: 12, w: 196, h: 310 }, @@ -157,6 +159,7 @@ class HouseScene extends Phaser.Scene { this.playerAnimClock = 0 this.playerDragging = false this.lastPlayerDragX = null + this.playerDragTarget = null } preload() { @@ -249,6 +252,7 @@ class HouseScene extends Phaser.Scene { if (object.getData('kind') !== 'player' || this.decorateMode) return this.playerDragging = true this.lastPlayerDragX = object.x + this.playerDragTarget = { x: object.x, y: object.y } this.animatePlayer('walk', 999) }) @@ -260,31 +264,27 @@ class HouseScene extends Phaser.Scene { let floor = this.state.player.floor ?? floorFromY(object.y) const nearStairs = dragX >= STAIRS_X + const targetX = Phaser.Math.Clamp(dragX, HOUSE_BOUNDS.left, HOUSE_BOUNDS.right) + let targetY = dragY + PLAYER_DRAG_OFFSET_Y if (nearStairs && floor === 'lower' && dragY < 475) { floor = 'upper' this.state.player.floor = floor - dragY = HOUSE_BOUNDS.upper.homeY + targetY = HOUSE_BOUNDS.upper.homeY } else if (nearStairs && floor === 'upper' && dragY > 430) { floor = 'lower' this.state.player.floor = floor - dragY = HOUSE_BOUNDS.lower.homeY + targetY = HOUSE_BOUNDS.lower.homeY } const bounds = floorBounds(floor) + targetY = Phaser.Math.Clamp(targetY, bounds.minY, bounds.maxY) + const previousX = this.lastPlayerDragX ?? object.x + if (Math.abs(targetX - previousX) > 1) object.setFlipX(targetX < previousX) + this.lastPlayerDragX = targetX - object.x = Phaser.Math.Clamp(dragX, HOUSE_BOUNDS.left, HOUSE_BOUNDS.right) - object.y = Phaser.Math.Clamp(dragY, bounds.minY, bounds.maxY) - - if (Math.abs(object.x - previousX) > 1) object.setFlipX(object.x < previousX) - this.lastPlayerDragX = object.x - - const depthT = Phaser.Math.Clamp((object.y - bounds.minY) / (bounds.maxY - bounds.minY), 0, 1) - object.setScale(Phaser.Math.Linear(0.32, 0.39, depthT)) - object.setDepth(Math.floor(object.y) + 40) - - this.capturePlayer() + this.playerDragTarget = { x: targetX, y: targetY } return } @@ -300,11 +300,32 @@ class HouseScene extends Phaser.Scene { if (kind === 'player') { if (this.decorateMode) return + this.playerDragging = false this.lastPlayerDragX = null - this.animatePlayer('idle', 999) - this.capturePlayer() - this.scheduleSave() + + const target = this.playerDragTarget ?? { x: object.x, y: object.y } + const floor = this.state.player.floor ?? floorFromY(target.y) + const bounds = floorBounds(floor) + + this.tweens.add({ + targets: object, + x: Phaser.Math.Clamp(target.x, HOUSE_BOUNDS.left, HOUSE_BOUNDS.right), + y: Phaser.Math.Clamp(target.y, bounds.minY, bounds.maxY), + duration: 110, + ease: 'Quad.out', + onUpdate: () => { + const depthT = Phaser.Math.Clamp((object.y - bounds.minY) / (bounds.maxY - bounds.minY), 0, 1) + object.setScale(Phaser.Math.Linear(0.32, 0.39, depthT)) + object.setDepth(Math.floor(object.y) + 40) + }, + onComplete: () => { + this.playerDragTarget = null + this.animatePlayer('idle', 999) + this.capturePlayer() + this.scheduleSave() + } + }) return } @@ -475,7 +496,20 @@ class HouseScene extends Phaser.Scene { update(_time, delta) { if (!this.player || this.decorateMode || this.tweens.isTweening(this.player)) return - if (this.playerDragging) { + if (this.playerDragging && this.playerDragTarget) { + const floor = this.state.player.floor ?? floorFromY(this.player.y) + const bounds = floorBounds(floor) + const follow = 1 - Math.pow(1 - PLAYER_DRAG_FOLLOW, delta / 16.667) + + this.player.x = Phaser.Math.Linear(this.player.x, this.playerDragTarget.x, follow) + this.player.y = Phaser.Math.Linear(this.player.y, this.playerDragTarget.y, follow) + + const depthT = Phaser.Math.Clamp((this.player.y - bounds.minY) / (bounds.maxY - bounds.minY), 0, 1) + this.player.setScale(Phaser.Math.Linear(0.32, 0.39, depthT)) + this.player.setDepth(Math.floor(this.player.y) + 40) + + this.state.player.x = Math.round(this.player.x) + this.state.player.y = Math.round(this.player.y) this.animatePlayer('walk', delta) return } @@ -551,7 +585,7 @@ const game = new Phaser.Game({ }) window.__DOLLHOUSE__ = { - version: '0.3.0', + version: '0.3.1', game, async resetAll() { await clearGameState()