fix: improve inventory item drag-and-drop behavior

- Use `snapBack` instead of immediate coordinate reset when a drag fails
- Adjust grid snapping calculation to use center-relative coordinates
- Validate item placement by simulating removal from the grid first
This commit is contained in:
hypercross 2026-04-20 19:22:55 +08:00
parent fd41db2a89
commit b2862e34d9
2 changed files with 10 additions and 5 deletions

View File

@ -127,8 +127,8 @@ export class InventoryItemContainer extends Phaser.GameObjects.Container {
} else if (event.type === DragDropEventType.UP) { } else if (event.type === DragDropEventType.UP) {
this.setAlpha(1); this.setAlpha(1);
if (!this.handleDragEnd()) { if (!this.handleDragEnd()) {
this.x = startX; const t = this.item.peek()?.transform;
this.y = startY; t && this.snapBack(t);
} }
startX = startY = 0; startX = startY = 0;
} }
@ -146,8 +146,8 @@ export class InventoryItemContainer extends Phaser.GameObjects.Container {
const x = this.x - this.gridOffsetX; const x = this.x - this.gridOffsetX;
const y = this.y - this.gridOffsetY; const y = this.y - this.gridOffsetY;
const targetX = Math.round((x - cellSize / 2) / cellSize); const targetX = Math.round(x / cellSize);
const targetY = Math.round((y - cellSize / 2) / cellSize); const targetY = Math.round(y / cellSize);
const clampedX = Math.max(0, Math.min(targetX, 10 - shapeWidth)); const clampedX = Math.max(0, Math.min(targetX, 10 - shapeWidth));
const clampedY = Math.max(0, Math.min(targetY, 10 - shapeHeight)); const clampedY = Math.max(0, Math.min(targetY, 10 - shapeHeight));

View File

@ -1,3 +1,4 @@
import { create } from "mutative";
import { mutableSignal } from "boardgame-core"; import { mutableSignal } from "boardgame-core";
import { import {
createGridInventory, createGridInventory,
@ -47,7 +48,11 @@ export function moveItem(
...item.transform, ...item.transform,
offset: { x: newX, y: newY }, offset: { x: newX, y: newY },
}; };
const validation = validatePlacement(inventory, item.shape, newTransform);
const removed = create(inventory, (inv) => {
removeItemFromGrid(inv, itemId);
});
const validation = validatePlacement(removed, item.shape, newTransform);
if (!validation.valid) return false; if (!validation.valid) return false;
inventorySignal.produce((inv) => { inventorySignal.produce((inv) => {