skyjo-fe/src/objects/cards.ts
2023-10-02 14:47:13 +02:00

155 lines
4.1 KiB
TypeScript

import {
BoxGeometry,
TextureLoader,
MeshBasicMaterial,
SRGBColorSpace,
Vector3,
Mesh,
Object3DEventMap,
Object3D,
} from "three";
import { Card, Deck, VisualColumn, VisualDeck } from "../types/gameTypes";
const textureLoader = new TextureLoader();
const cardSize = 5;
const cardGeometry = new BoxGeometry(
cardSize * 0.4,
cardSize * 0.001,
cardSize * 0.6
);
const getCardTexture = (value: number | null) => {
let cardTexture;
switch (value) {
case -2:
cardTexture = textureLoader.load("/textures/card-minus2.png");
break;
case -1:
cardTexture = textureLoader.load("/textures/card-minus1.png");
break;
case 0:
cardTexture = textureLoader.load("/textures/card-0.png");
break;
case 1:
cardTexture = textureLoader.load("/textures/card-1.png");
break;
case 2:
cardTexture = textureLoader.load("/textures/card-2.png");
break;
case 3:
cardTexture = textureLoader.load("/textures/card-3.png");
break;
case 4:
cardTexture = textureLoader.load("/textures/card-4.png");
break;
case 5:
cardTexture = textureLoader.load("/textures/card-5.png");
break;
case 6:
cardTexture = textureLoader.load("/textures/card-6.png");
break;
case 7:
cardTexture = textureLoader.load("/textures/card-7.png");
break;
case 8:
cardTexture = textureLoader.load("/textures/card-8.png");
break;
case 9:
cardTexture = textureLoader.load("/textures/card-9.png");
break;
case 10:
cardTexture = textureLoader.load("/textures/card-10.png");
break;
case 11:
cardTexture = textureLoader.load("/textures/card-11.png");
break;
case 12:
cardTexture = textureLoader.load("/textures/card-12.png");
break;
case null:
cardTexture = textureLoader.load("/textures/card-back.png");
break;
default:
cardTexture = textureLoader.load("/textures/card-back.png");
break;
}
cardTexture.colorSpace = SRGBColorSpace;
return cardTexture;
};
export const createCard = (
card: Card,
position: Vector3,
faceUp: boolean = false
) => {
const cardMaterial = [
new MeshBasicMaterial(),
new MeshBasicMaterial(),
new MeshBasicMaterial({ map: getCardTexture(null) }), // X = backside
new MeshBasicMaterial({ map: getCardTexture(card) }),
new MeshBasicMaterial(),
new MeshBasicMaterial(),
];
const visualCard = new Mesh(cardGeometry, cardMaterial);
visualCard.name = card !== null ? card.toString() : "Facedown card";
visualCard.position.copy(position);
if (faceUp) {
visualCard.rotation.x = Math.PI;
}
return visualCard;
};
export const createPlayerCards = (deck: Deck, positionReference: Vector3) => {
const playerDeck: Object3D[][] = [];
let visualColumn: Object3D[] = [];
deck.forEach((column, columnIndex) => {
column.forEach((card, cardIndex) => {
const cardPositionX = positionReference.x + columnIndex * 4 - 6;
const cardPositionY = positionReference.y;
const cardPositionZ = positionReference.z + cardIndex * 4 - 8;
const cardPosition = new Vector3(
cardPositionX,
cardPositionY,
cardPositionZ
);
const playerCard = createCard(card, cardPosition);
visualColumn.push(playerCard);
if (cardIndex === 2) {
playerDeck.push(visualColumn as VisualColumn);
visualColumn = [];
}
});
});
return playerDeck as VisualDeck;
};
export const createCardStaple = (
cards: Card[],
positionReference: Vector3,
faceUp: boolean = false
) => {
const cardStackCards: Mesh<
BoxGeometry,
MeshBasicMaterial[],
Object3DEventMap
>[] = [];
cards.forEach((card: Card, index: number) => {
const cardPositionX = positionReference.x;
const cardPositionY = positionReference.y + index * 0.01;
const cardPositionZ = positionReference.z;
const cardPosition = new Vector3(
cardPositionX,
cardPositionY,
cardPositionZ
);
const cardStackCard = createCard(card, cardPosition, faceUp);
cardStackCards.push(cardStackCard);
});
return cardStackCards;
};