Smooth character drag follow behind touch

This commit is contained in:
Admin 2026-09-21 23:07:38 +00:00
parent 0c9ddfef5c
commit b528b4fe65

View File

@ -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
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()