fix: inventory interaction
This commit is contained in:
parent
28a2623bd1
commit
0ecef16a4a
|
|
@ -33,11 +33,16 @@ interface DragState {
|
||||||
itemMeta: InventoryItem<GameItemMeta>['meta'];
|
itemMeta: InventoryItem<GameItemMeta>['meta'];
|
||||||
ghostContainer: Phaser.GameObjects.Container;
|
ghostContainer: Phaser.GameObjects.Container;
|
||||||
previewGraphics: Phaser.GameObjects.Graphics;
|
previewGraphics: Phaser.GameObjects.Graphics;
|
||||||
|
dragOffsetX: number;
|
||||||
|
dragOffsetY: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LostItem {
|
interface LostItem {
|
||||||
id: string;
|
id: string;
|
||||||
container: Phaser.GameObjects.Container;
|
container: Phaser.GameObjects.Container;
|
||||||
|
shape: InventoryItem<GameItemMeta>['shape'];
|
||||||
|
transform: InventoryItem<GameItemMeta>['transform'];
|
||||||
|
meta: InventoryItem<GameItemMeta>['meta'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InventoryWidget {
|
export class InventoryWidget {
|
||||||
|
|
@ -76,13 +81,13 @@ export class InventoryWidget {
|
||||||
|
|
||||||
this.container = this.scene.add.container(options.x, options.y);
|
this.container = this.scene.add.container(options.x, options.y);
|
||||||
|
|
||||||
|
this.pointerMoveHandler = this.onPointerMove.bind(this);
|
||||||
|
this.pointerUpHandler = this.onPointerUp.bind(this);
|
||||||
|
|
||||||
this.drawGridBackground(inventory.width, inventory.height, gridW, gridH);
|
this.drawGridBackground(inventory.width, inventory.height, gridW, gridH);
|
||||||
this.drawItems();
|
this.drawItems();
|
||||||
this.setupInput();
|
this.setupInput();
|
||||||
|
|
||||||
this.pointerMoveHandler = this.onPointerMove.bind(this);
|
|
||||||
this.pointerUpHandler = this.onPointerUp.bind(this);
|
|
||||||
|
|
||||||
this.scene.events.once('shutdown', () => this.destroy());
|
this.scene.events.once('shutdown', () => this.destroy());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,7 +210,14 @@ export class InventoryWidget {
|
||||||
});
|
});
|
||||||
this.removeItemVisuals(itemId);
|
this.removeItemVisuals(itemId);
|
||||||
|
|
||||||
const ghostContainer = this.scene.add.container(pointer.x, pointer.y).setDepth(1000);
|
const cells = this.getItemCells(item);
|
||||||
|
const firstCell = cells[0];
|
||||||
|
const itemWorldX = this.container.x + this.gridX + firstCell.x * (this.cellSize + this.gridGap);
|
||||||
|
const itemWorldY = this.container.y + this.gridY + firstCell.y * (this.cellSize + this.gridGap);
|
||||||
|
const dragOffsetX = pointer.x - itemWorldX;
|
||||||
|
const dragOffsetY = pointer.y - itemWorldY;
|
||||||
|
|
||||||
|
const ghostContainer = this.scene.add.container(itemWorldX, itemWorldY).setDepth(1000);
|
||||||
const ghostGraphics = this.scene.add.graphics();
|
const ghostGraphics = this.scene.add.graphics();
|
||||||
const color = this.colorMap.get(itemId) ?? 0x888888;
|
const color = this.colorMap.get(itemId) ?? 0x888888;
|
||||||
|
|
||||||
|
|
@ -230,6 +242,42 @@ export class InventoryWidget {
|
||||||
itemMeta: item.meta,
|
itemMeta: item.meta,
|
||||||
ghostContainer,
|
ghostContainer,
|
||||||
previewGraphics,
|
previewGraphics,
|
||||||
|
dragOffsetX,
|
||||||
|
dragOffsetY,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private startLostItemDrag(itemId: string, pointer: Phaser.Input.Pointer): void {
|
||||||
|
const lost = this.lostItems.get(itemId);
|
||||||
|
if (!lost) return;
|
||||||
|
|
||||||
|
lost.container.destroy();
|
||||||
|
this.lostItems.delete(itemId);
|
||||||
|
|
||||||
|
const ghostContainer = this.scene.add.container(pointer.x, pointer.y).setDepth(1000);
|
||||||
|
const ghostGraphics = this.scene.add.graphics();
|
||||||
|
const color = this.colorMap.get(itemId) ?? 0x888888;
|
||||||
|
|
||||||
|
const cells = transformShape(lost.shape, lost.transform);
|
||||||
|
for (const cell of cells) {
|
||||||
|
ghostGraphics.fillStyle(color, 0.7);
|
||||||
|
ghostGraphics.fillRect(cell.x * (this.cellSize + this.gridGap), cell.y * (this.cellSize + this.gridGap), this.cellSize - 2, this.cellSize - 2);
|
||||||
|
ghostGraphics.lineStyle(2, 0xffffff);
|
||||||
|
ghostGraphics.strokeRect(cell.x * (this.cellSize + this.gridGap), cell.y * (this.cellSize + this.gridGap), this.cellSize, this.cellSize);
|
||||||
|
}
|
||||||
|
ghostContainer.add(ghostGraphics);
|
||||||
|
|
||||||
|
const previewGraphics = this.scene.add.graphics().setDepth(999).setAlpha(0.5);
|
||||||
|
|
||||||
|
this.dragState = {
|
||||||
|
itemId,
|
||||||
|
itemShape: lost.shape,
|
||||||
|
itemTransform: { ...lost.transform, offset: { ...lost.transform.offset } },
|
||||||
|
itemMeta: lost.meta,
|
||||||
|
ghostContainer,
|
||||||
|
previewGraphics,
|
||||||
|
dragOffsetX: 0,
|
||||||
|
dragOffsetY: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -265,9 +313,9 @@ export class InventoryWidget {
|
||||||
private onPointerMove(pointer: Phaser.Input.Pointer): void {
|
private onPointerMove(pointer: Phaser.Input.Pointer): void {
|
||||||
if (!this.dragState) return;
|
if (!this.dragState) return;
|
||||||
|
|
||||||
this.dragState.ghostContainer.setPosition(pointer.x, pointer.y);
|
this.dragState.ghostContainer.setPosition(pointer.x - this.dragState.dragOffsetX, pointer.y - this.dragState.dragOffsetY);
|
||||||
|
|
||||||
const gridCell = this.getWorldGridCell(pointer.x, pointer.y);
|
const gridCell = this.getWorldGridCell(pointer.x - this.dragState.dragOffsetX, pointer.y - this.dragState.dragOffsetY);
|
||||||
this.dragState.previewGraphics.clear();
|
this.dragState.previewGraphics.clear();
|
||||||
|
|
||||||
if (gridCell) {
|
if (gridCell) {
|
||||||
|
|
@ -298,7 +346,7 @@ export class InventoryWidget {
|
||||||
private onPointerUp(pointer: Phaser.Input.Pointer): void {
|
private onPointerUp(pointer: Phaser.Input.Pointer): void {
|
||||||
if (!this.dragState) return;
|
if (!this.dragState) return;
|
||||||
|
|
||||||
const gridCell = this.getWorldGridCell(pointer.x, pointer.y);
|
const gridCell = this.getWorldGridCell(pointer.x - this.dragState.dragOffsetX, pointer.y - this.dragState.dragOffsetY);
|
||||||
const inventory = this.getInventory();
|
const inventory = this.getInventory();
|
||||||
|
|
||||||
this.dragState.ghostContainer.destroy();
|
this.dragState.ghostContainer.destroy();
|
||||||
|
|
@ -345,6 +393,10 @@ export class InventoryWidget {
|
||||||
const cellX = Math.floor(localX / (this.cellSize + this.gridGap));
|
const cellX = Math.floor(localX / (this.cellSize + this.gridGap));
|
||||||
const cellY = Math.floor(localY / (this.cellSize + this.gridGap));
|
const cellY = Math.floor(localY / (this.cellSize + this.gridGap));
|
||||||
|
|
||||||
|
if (cellX < 0 || cellY < 0 || cellX >= this.getInventory().width || cellY >= this.getInventory().height) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return { x: cellX, y: cellY };
|
return { x: cellX, y: cellY };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -376,7 +428,24 @@ export class InventoryWidget {
|
||||||
}).setOrigin(0.5);
|
}).setOrigin(0.5);
|
||||||
container.add(text);
|
container.add(text);
|
||||||
|
|
||||||
this.lostItems.set(this.dragState.itemId, { id: this.dragState.itemId, container });
|
const hitRect = new Phaser.Geom.Rectangle(0, 0, this.cellSize, this.cellSize);
|
||||||
|
container.setInteractive(hitRect, Phaser.Geom.Rectangle.Contains);
|
||||||
|
|
||||||
|
container.on('pointerdown', (pointer: Phaser.Input.Pointer) => {
|
||||||
|
if (this.isLocked) return;
|
||||||
|
if (this.dragState) return;
|
||||||
|
if (pointer.button === 0) {
|
||||||
|
this.startLostItemDrag(this.dragState!.itemId, pointer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.lostItems.set(this.dragState.itemId, {
|
||||||
|
id: this.dragState.itemId,
|
||||||
|
container,
|
||||||
|
shape: this.dragState.itemShape,
|
||||||
|
transform: { ...this.dragState.itemTransform },
|
||||||
|
meta: this.dragState.itemMeta,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeItemVisuals(itemId: string): void {
|
private removeItemVisuals(itemId: string): void {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue