Make character touch-drag controlled

This commit is contained in:
Admin 2026-09-21 22:57:21 +00:00
parent 289517dd81
commit 0c9ddfef5c

View File

@ -155,6 +155,8 @@ class HouseScene extends Phaser.Scene {
this.playerAnimMode = 'idle'
this.playerAnimFrame = 0
this.playerAnimClock = 0
this.playerDragging = false
this.lastPlayerDragX = null
}
preload() {
@ -184,7 +186,6 @@ class HouseScene extends Phaser.Scene {
.setDepth(0)
this.buildUi()
this.buildControls()
this.bindInput()
this.spawnAllFurniture()
this.spawnPlayer()
@ -233,53 +234,82 @@ class HouseScene extends Phaser.Scene {
.setScrollFactor(0)
.setDepth(990)
this.stairsHint = this.add.text(480, 684, 'Use the stairs on the right to change floors ↑ ↓', {
this.stairsHint = this.add.text(480, 684, 'Drag her around • use the stairs on the right to change floors', {
fontFamily: 'Arial Rounded MT Bold, ui-rounded, sans-serif',
fontSize: '13px',
color: '#7a526b'
}).setOrigin(0.5).setScrollFactor(0).setDepth(1001)
}
buildControls() {
const makePad = (x, label, direction) => {
const circle = this.add.circle(x, 687, 25, 0xffffff, 0.94)
.setStrokeStyle(2, 0xd889aa)
.setInteractive()
.setScrollFactor(0)
.setDepth(1010)
this.add.text(x, 686, label, {
fontFamily: 'Arial, sans-serif',
fontSize: '23px',
color: '#b75c83',
fontStyle: 'bold'
}).setOrigin(0.5).setScrollFactor(0).setDepth(1011)
const off = () => { this.moveIntent[direction] = false }
circle.on('pointerdown', () => { this.moveIntent[direction] = true })
circle.on('pointerup', off)
circle.on('pointerout', off)
}
makePad(44, '◀', 'left')
makePad(100, '▶', 'right')
makePad(156, '▲', 'up')
makePad(212, '▼', 'down')
}
bindInput() {
this.cursors = this.input.keyboard.createCursorKeys()
this.keys = this.input.keyboard.addKeys('W,A,S,D')
this.input.on('dragstart', (_pointer, object) => {
if (object.getData('kind') !== 'player' || this.decorateMode) return
this.playerDragging = true
this.lastPlayerDragX = object.x
this.animatePlayer('walk', 999)
})
this.input.on('drag', (_pointer, object, dragX, dragY) => {
if (!this.decorateMode || object.getData('kind') !== 'furniture') return
const kind = object.getData('kind')
if (kind === 'player') {
if (this.decorateMode) return
let floor = this.state.player.floor ?? floorFromY(object.y)
const nearStairs = dragX >= STAIRS_X
if (nearStairs && floor === 'lower' && dragY < 475) {
floor = 'upper'
this.state.player.floor = floor
dragY = HOUSE_BOUNDS.upper.homeY
} else if (nearStairs && floor === 'upper' && dragY > 430) {
floor = 'lower'
this.state.player.floor = floor
dragY = HOUSE_BOUNDS.lower.homeY
}
const bounds = floorBounds(floor)
const previousX = this.lastPlayerDragX ?? object.x
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()
return
}
if (!this.decorateMode || kind !== 'furniture') return
object.x = Phaser.Math.Clamp(dragX, HOUSE_BOUNDS.left + 28, HOUSE_BOUNDS.right - 28)
object.y = Phaser.Math.Clamp(dragY, 250, HOUSE_BOUNDS.lower.maxY)
object.setDepth(Math.floor(object.y))
})
this.input.on('dragend', (_pointer, object) => {
if (object.getData('kind') !== 'furniture') return
const kind = object.getData('kind')
if (kind === 'player') {
if (this.decorateMode) return
this.playerDragging = false
this.lastPlayerDragX = null
this.animatePlayer('idle', 999)
this.capturePlayer()
this.scheduleSave()
return
}
if (kind !== 'furniture') return
const item = this.state.items.find((entry) => entry.id === object.getData('id'))
if (!item) return
@ -326,6 +356,9 @@ class HouseScene extends Phaser.Scene {
.setOrigin(0.5, 1)
.setScale(0.36)
.setDepth(Math.floor(this.state.player.y) + 40)
.setData('kind', 'player')
.setInteractive({ cursor: 'grab' })
this.input.setDraggable(this.player)
}
animatePlayer(mode, delta) {
@ -354,7 +387,7 @@ class HouseScene extends Phaser.Scene {
this.modeButton.text.setText(this.decorateMode ? '✓ Done decorating' : '✨ Decorate')
const nextType = FURNITURE_ORDER[this.addIndex % FURNITURE_ORDER.length]
this.addButton.text.setText('+ Add ' + FURNITURE_NAMES[nextType])
this.helpText.setText(this.decorateMode ? 'drag furniture' : 'walk & play')
this.helpText.setText(this.decorateMode ? 'drag furniture' : 'drag her to move')
this.itemSprites.forEach((sprite) => {
sprite.setAlpha(this.decorateMode ? 1 : 0.98)
@ -442,6 +475,11 @@ class HouseScene extends Phaser.Scene {
update(_time, delta) {
if (!this.player || this.decorateMode || this.tweens.isTweening(this.player)) return
if (this.playerDragging) {
this.animatePlayer('walk', delta)
return
}
this.stairCooldown = Math.max(0, this.stairCooldown - delta)
const left = this.cursors.left.isDown || this.keys.A.isDown || this.moveIntent.left
@ -513,7 +551,7 @@ const game = new Phaser.Game({
})
window.__DOLLHOUSE__ = {
version: '0.2.0',
version: '0.3.0',
game,
async resetAll() {
await clearGameState()