diff --git a/packages/sts-like-viewer/src/gameobjects/InventoryItemContainer.ts b/packages/sts-like-viewer/src/gameobjects/InventoryItemContainer.ts index e986f92..d306807 100644 --- a/packages/sts-like-viewer/src/gameobjects/InventoryItemContainer.ts +++ b/packages/sts-like-viewer/src/gameobjects/InventoryItemContainer.ts @@ -2,15 +2,14 @@ import Phaser from "phaser"; import { dragDropEventEffect, DragDropEventType } from "boardgame-phaser"; import { GRID_CONFIG } from "@/config"; import { - IDENTITY_TRANSFORM, ParsedShape, + Point2D, Transform2D, transformShape, type GameItem, } from "boardgame-core/samples/slay-the-spire-like"; import { DisposableBag } from "../../../framework/dist"; import { InventoryItemState } from "@/state/InventoryItemState"; -import { effect } from "@preact/signals-core"; export interface InventoryItemContainerCallbacks { onMoveItem: ( @@ -23,6 +22,7 @@ export interface InventoryItemContainerCallbacks { export class InventoryItemContainer extends Phaser.GameObjects.Container { private itemState: InventoryItemState; + private hitArea: Point2D[] = []; constructor( scene: Phaser.Scene, @@ -41,6 +41,7 @@ export class InventoryItemContainer extends Phaser.GameObjects.Container { GRID_CONFIG.ITEM_NAME_STYLE, ); this.add([graphics, label]); + this.setupInteractive(); this.itemState = new InventoryItemState(); @@ -50,20 +51,18 @@ export class InventoryItemContainer extends Phaser.GameObjects.Container { label.setText(this.itemState.name.value); }); - disposables.add( - effect(() => { - graphics.clear(); - if (!this.itemState.shape.value) return; - const cellRects = this.renderGraphics( - graphics, - this.itemState.shape.value, - this.itemState.color.value, - this.itemState.previewRotation.value, - ); + disposables.add(this.setupDnDEffect()); - return this.setupInteractive(cellRects); - }), - ); + disposables.addEffect(() => { + graphics.clear(); + if (!this.itemState.shape.value) return; + this.hitArea = this.renderGraphics( + graphics, + this.itemState.shape.value, + this.itemState.color.value, + this.itemState.previewRotation.value, + ); + }); disposables.addEffect(() => { if (!this.itemState.transform.value) return; @@ -81,7 +80,7 @@ export class InventoryItemContainer extends Phaser.GameObjects.Container { shape: ParsedShape, itemColor: number, rotation: number, - ): { x: number; y: number }[] { + ) { const transform: Transform2D = { offset: { x: 0, y: 0 }, rotation, @@ -109,17 +108,17 @@ export class InventoryItemContainer extends Phaser.GameObjects.Container { return cellRects; } - private setupInteractive(cellRects: { x: number; y: number }[]) { + private setupInteractive() { this.setScrollFactor(0); const cellSize = GRID_CONFIG.VIEWER_CELL_SIZE; this.setInteractive({ - hitArea: cellRects, + hitArea: this, hitAreaCallback: ( - hitArea: { x: number; y: number }[], + hitArea: InventoryItemContainer, x: number, y: number, ) => - hitArea.some( + hitArea.hitArea.some( (cell) => x >= cell.x && x < cell.x + cellSize && @@ -128,11 +127,12 @@ export class InventoryItemContainer extends Phaser.GameObjects.Container { ), useHandCursor: true, } as Phaser.Types.Input.InputConfiguration); + } + private setupDnDEffect() { let startX = 0; let startY = 0; return dragDropEventEffect(this, (event) => { - console.log(event.type); if (event.type === DragDropEventType.DOWN) { startX = this.x; startY = this.y; @@ -141,8 +141,7 @@ export class InventoryItemContainer extends Phaser.GameObjects.Container { this.x = startX + event.deltaX; this.y = startY + event.deltaY; } else if (event.type === DragDropEventType.ALTBUTTON) { - const current = this.itemState.previewRotation.peek(); - this.itemState.setPreviewRotation(current + 90); + this.itemState.addPreviewRotation(90); } else if (event.type === DragDropEventType.UP) { this.setAlpha(1); const finalRotation = this.itemState.previewRotation.peek(); diff --git a/packages/sts-like-viewer/src/state/InventoryItemState.ts b/packages/sts-like-viewer/src/state/InventoryItemState.ts index 93af969..e0c67f0 100644 --- a/packages/sts-like-viewer/src/state/InventoryItemState.ts +++ b/packages/sts-like-viewer/src/state/InventoryItemState.ts @@ -33,7 +33,7 @@ export class InventoryItemState { this.previewRotation = computed(() => { const base = this._item.value?.transform?.rotation ?? 0; - return base + this._previewRotation.value; + return (base + this._previewRotation.value) % 360; }); } @@ -50,6 +50,10 @@ export class InventoryItemState { this._previewRotation.value = rotation; } + addPreviewRotation(rotation: number): void { + this._previewRotation.value += rotation; + } + private computeColor(itemId: string): number { const hash = itemId.split("").reduce((acc, c) => acc + c.charCodeAt(0), 0); return ITEM_COLORS[hash % ITEM_COLORS.length];