From cf4f3832ff05b95de812cf019b44bfa3a29698ed Mon Sep 17 00:00:00 2001 From: Nolan Hellyer Date: Mon, 3 Nov 2025 08:40:13 -0800 Subject: [PATCH] refactor hand positioning, add dealer hand. --- client/src/Hand.ts | 40 +++++++++++++++++++++++++++------------- client/src/constants.ts | 1 + client/src/main.ts | 40 +++++++++++++++++++++++++++++++++------- 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/client/src/Hand.ts b/client/src/Hand.ts index 62bedca..a313368 100644 --- a/client/src/Hand.ts +++ b/client/src/Hand.ts @@ -1,6 +1,8 @@ -import { Assets, Container, Size, PointData, Sprite } from "pixi.js"; +import { Assets, Container, Sprite } from "pixi.js"; import { Card } from "./Card"; -import { CARD_HEIGHT, CARD_WIDTH } from "./constants"; +import { CARD_HOVER_DIST, CARD_WIDTH } from "./constants"; + +type Pivot = "left" | "right" | "center"; const spritesheet = await Assets.load("/public/assets/cards.json"); @@ -8,7 +10,7 @@ export class Hand { #cards: Sprite[]; #container: Container; #maxWidth: number; - #parent: Size & PointData; + #pivot: Pivot; constructor(maxWidth: number, cards: Card[] = []) { if (maxWidth < CARD_WIDTH) { @@ -17,7 +19,7 @@ export class Hand { this.#maxWidth = maxWidth; this.#container = new Container(); - this.#parent = { x: 0, y: 0, width: 0, height: 0 }; + this.#pivot = "left"; if (cards.length > 0) { const sprites: Sprite[] = []; @@ -37,25 +39,37 @@ export class Hand { const sprite = new Sprite(spritesheet.textures[card]); sprite.eventMode = "dynamic"; sprite.onmouseenter = () => { - sprite.y -= 50; + sprite.y -= CARD_HOVER_DIST; }; sprite.onmouseleave = () => { - sprite.y += 50; + sprite.y += CARD_HOVER_DIST; }; this.#cards.push(sprite); this.#container.addChild(sprite); this.fanCards(); - this.repositionContainer(); + this.setPivot(this.#pivot); } - parentArea(x: number, y: number, width: number, height: number) { - this.#parent = { x, y, width, height }; - this.repositionContainer(); + setPosition(x: number, y: number) { + this.#container.position.set(x, y); } - repositionContainer() { - this.#container.pivot.set(this.#container.width / 2, CARD_HEIGHT); - this.#container.position.set(this.#parent.width / 2, this.#parent.height); + setPivot(pivot: "left" | "right" | "center") { + switch (pivot) { + case "left": + this.#container.pivot.set(0, 0); + break; + case "right": + this.#container.pivot.set(this.#container.width, 0); + break; + case "center": + this.#container.pivot.set(this.#container.width / 2, 0); + break; + default: + throw new Error(`unknown pivot position: ${pivot}`); + } + + this.#pivot = pivot; } fanCards() { diff --git a/client/src/constants.ts b/client/src/constants.ts index adb8c09..fbee1a9 100644 --- a/client/src/constants.ts +++ b/client/src/constants.ts @@ -1,2 +1,3 @@ export const CARD_WIDTH = 144; export const CARD_HEIGHT = 224; +export const CARD_HOVER_DIST = 50; diff --git a/client/src/main.ts b/client/src/main.ts index b6e166e..e511a93 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -1,8 +1,9 @@ import { Application } from "pixi.js"; import { Hand } from "./Hand"; import { Card } from "./Card"; +import { CARD_HEIGHT, CARD_HOVER_DIST } from "./constants"; -const cards: Card[] = [ +const playerCards: Card[] = [ "threeOfClubs", "twoOfDiamonds", "aceOfClubs", @@ -11,6 +12,8 @@ const cards: Card[] = [ "sixOfClubs", ]; +const dealerCards: Card[] = ["aceOfHearts"]; + (async () => { try { // Create and initialize a new application @@ -24,11 +27,27 @@ const cards: Card[] = [ // Append the application canvas to the document body document.getElementById("pixi-container")!.appendChild(app.canvas); - const hand = new Hand(350, []); + const playerHand = new Hand(350, []); + const dealerHand = new Hand(350, []); - hand.parentArea(0, 0, app.screen.width, app.screen.height); + const positionPlayer = () => { + playerHand.setPivot("center"); + playerHand.setPosition( + app.screen.width / 2, + app.screen.height - CARD_HEIGHT + CARD_HOVER_DIST, + ); + }; - app.stage.addChild(hand.getContainer()); + const positionDealer = () => { + dealerHand.setPivot("center"); + dealerHand.setPosition(app.screen.width / 2, 0 + CARD_HOVER_DIST); + }; + + positionPlayer(); + positionDealer(); + + app.stage.addChild(playerHand.getContainer()); + app.stage.addChild(dealerHand.getContainer()); // When the user resizes the window, resize the app. There is a plugin // for doing this automatically, but it doesn't reposition stage's @@ -41,16 +60,23 @@ const cards: Card[] = [ // https://pixijs.com/8.x/guides/concepts/scene-graph#local-vs-global-coordinates window.addEventListener?.("resize", () => { app.renderer.resize(window.innerWidth, window.innerHeight); - hand.parentArea(0, 0, app.screen.width, app.screen.height); + positionPlayer(); + positionDealer(); }); let ms = 0; let elapsed = 0; app.ticker.add((time) => { elapsed += time.elapsedMS; - if (cards.length && elapsed >= ms) { + if (elapsed >= ms) { ms += 300; - hand.add(cards.pop()!); + if (playerCards.length) { + playerHand.add(playerCards.pop()!); + } + + if (dealerCards.length) { + dealerHand.add(dealerCards.pop()!); + } } }); } catch (err) {