refactor hand positioning, add dealer hand.

This commit is contained in:
2025-11-03 08:40:13 -08:00
parent f9c95993c4
commit cf4f3832ff
3 changed files with 61 additions and 20 deletions

View File

@ -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 } 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"); const spritesheet = await Assets.load("/public/assets/cards.json");
@ -8,7 +10,7 @@ export class Hand {
#cards: Sprite[]; #cards: Sprite[];
#container: Container; #container: Container;
#maxWidth: number; #maxWidth: number;
#parent: Size & PointData; #pivot: Pivot;
constructor(maxWidth: number, cards: Card[] = []) { constructor(maxWidth: number, cards: Card[] = []) {
if (maxWidth < CARD_WIDTH) { if (maxWidth < CARD_WIDTH) {
@ -17,7 +19,7 @@ export class Hand {
this.#maxWidth = maxWidth; this.#maxWidth = maxWidth;
this.#container = new Container(); this.#container = new Container();
this.#parent = { x: 0, y: 0, width: 0, height: 0 }; this.#pivot = "left";
if (cards.length > 0) { if (cards.length > 0) {
const sprites: Sprite[] = []; const sprites: Sprite[] = [];
@ -37,25 +39,37 @@ export class Hand {
const sprite = new Sprite(spritesheet.textures[card]); const sprite = new Sprite(spritesheet.textures[card]);
sprite.eventMode = "dynamic"; sprite.eventMode = "dynamic";
sprite.onmouseenter = () => { sprite.onmouseenter = () => {
sprite.y -= 50; sprite.y -= CARD_HOVER_DIST;
}; };
sprite.onmouseleave = () => { sprite.onmouseleave = () => {
sprite.y += 50; sprite.y += CARD_HOVER_DIST;
}; };
this.#cards.push(sprite); this.#cards.push(sprite);
this.#container.addChild(sprite); this.#container.addChild(sprite);
this.fanCards(); this.fanCards();
this.repositionContainer(); this.setPivot(this.#pivot);
} }
parentArea(x: number, y: number, width: number, height: number) { setPosition(x: number, y: number) {
this.#parent = { x, y, width, height }; this.#container.position.set(x, y);
this.repositionContainer();
} }
repositionContainer() { setPivot(pivot: "left" | "right" | "center") {
this.#container.pivot.set(this.#container.width / 2, CARD_HEIGHT); switch (pivot) {
this.#container.position.set(this.#parent.width / 2, this.#parent.height); 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() { fanCards() {

View File

@ -1,2 +1,3 @@
export const CARD_WIDTH = 144; export const CARD_WIDTH = 144;
export const CARD_HEIGHT = 224; export const CARD_HEIGHT = 224;
export const CARD_HOVER_DIST = 50;

View File

@ -1,8 +1,9 @@
import { Application } from "pixi.js"; import { Application } from "pixi.js";
import { Hand } from "./Hand"; import { Hand } from "./Hand";
import { Card } from "./Card"; import { Card } from "./Card";
import { CARD_HEIGHT, CARD_HOVER_DIST } from "./constants";
const cards: Card[] = [ const playerCards: Card[] = [
"threeOfClubs", "threeOfClubs",
"twoOfDiamonds", "twoOfDiamonds",
"aceOfClubs", "aceOfClubs",
@ -11,6 +12,8 @@ const cards: Card[] = [
"sixOfClubs", "sixOfClubs",
]; ];
const dealerCards: Card[] = ["aceOfHearts"];
(async () => { (async () => {
try { try {
// Create and initialize a new application // Create and initialize a new application
@ -24,11 +27,27 @@ const cards: Card[] = [
// Append the application canvas to the document body // Append the application canvas to the document body
document.getElementById("pixi-container")!.appendChild(app.canvas); 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 // When the user resizes the window, resize the app. There is a plugin
// for doing this automatically, but it doesn't reposition stage's // 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 // https://pixijs.com/8.x/guides/concepts/scene-graph#local-vs-global-coordinates
window.addEventListener?.("resize", () => { window.addEventListener?.("resize", () => {
app.renderer.resize(window.innerWidth, window.innerHeight); app.renderer.resize(window.innerWidth, window.innerHeight);
hand.parentArea(0, 0, app.screen.width, app.screen.height); positionPlayer();
positionDealer();
}); });
let ms = 0; let ms = 0;
let elapsed = 0; let elapsed = 0;
app.ticker.add((time) => { app.ticker.add((time) => {
elapsed += time.elapsedMS; elapsed += time.elapsedMS;
if (cards.length && elapsed >= ms) { if (elapsed >= ms) {
ms += 300; ms += 300;
hand.add(cards.pop()!); if (playerCards.length) {
playerHand.add(playerCards.pop()!);
}
if (dealerCards.length) {
dealerHand.add(dealerCards.pop()!);
}
} }
}); });
} catch (err) { } catch (err) {