diff --git a/public/mock-cards/arid_desert.webp b/public/mock-cards/arid_desert.webp new file mode 100644 index 0000000..fb7fce1 Binary files /dev/null and b/public/mock-cards/arid_desert.webp differ diff --git a/public/mock-cards/death_dealer.webp b/public/mock-cards/death_dealer.webp new file mode 100644 index 0000000..f4d3d43 Binary files /dev/null and b/public/mock-cards/death_dealer.webp differ diff --git a/public/mock-cards/infernal_legion.webp b/public/mock-cards/infernal_legion.webp new file mode 100644 index 0000000..460801e Binary files /dev/null and b/public/mock-cards/infernal_legion.webp differ diff --git a/public/mock-cards/jihad.webp b/public/mock-cards/jihad.webp new file mode 100644 index 0000000..73b0c5d Binary files /dev/null and b/public/mock-cards/jihad.webp differ diff --git a/public/mock-cards/sorcerer.webp b/public/mock-cards/sorcerer.webp new file mode 100644 index 0000000..16c368e Binary files /dev/null and b/public/mock-cards/sorcerer.webp differ diff --git a/public/mock-cards/wayfaring_pilgrim.webp b/public/mock-cards/wayfaring_pilgrim.webp new file mode 100644 index 0000000..87e5c17 Binary files /dev/null and b/public/mock-cards/wayfaring_pilgrim.webp differ diff --git a/src/components/atoms/mock-cards/card.tsx b/src/components/atoms/mock-cards/card.tsx index 042e043..227e0b9 100644 --- a/src/components/atoms/mock-cards/card.tsx +++ b/src/components/atoms/mock-cards/card.tsx @@ -56,13 +56,14 @@ export const CardImage = ({ position={show ? "absolute" : "unset"} h="310px" w="100%" - bgImage={`url(/mock-cards/${img})`} backgroundPosition="top" backgroundSize="cover" backgroundRepeat="no-repeat" transform={show ? "scale(1.5)" : "unset"} transition="all 0.25s ease" - // bg="gray.400" + style={{ + backgroundImage: `url(/mock-cards/${img})`, + }} />{" "} ); diff --git a/src/components/organisms/GameBoard/Layout.tsx b/src/components/organisms/GameBoard/Layout.tsx index f58543c..c1caefb 100644 --- a/src/components/organisms/GameBoard/Layout.tsx +++ b/src/components/organisms/GameBoard/Layout.tsx @@ -21,7 +21,7 @@ export const GameLayout = ( }} >

- Right click cards to view in full + Playtest cards on a grid. Click to tap. Right click to view big.

diff --git a/src/components/organisms/GameBoard/index.tsx b/src/components/organisms/GameBoard/index.tsx index eec5c61..c90dd8d 100644 --- a/src/components/organisms/GameBoard/index.tsx +++ b/src/components/organisms/GameBoard/index.tsx @@ -10,7 +10,6 @@ import { DragOverlay, } from "@dnd-kit/core"; import { useHandleDrag } from "./useHandleDrag"; -import { SorceryCard } from "@/types/card"; import { CardImage } from "@/components/atoms/mock-cards/card"; import { CardImage as FullCard } from "@/components/atoms/card-view/card"; import { SortableItem } from "@/components/molecules/SortItem"; @@ -19,15 +18,15 @@ import { Modal } from "@/components/atoms/Modal"; import { Dispatch, SetStateAction, useState } from "react"; import { FullCardAtlas } from "@/components/atoms/card-view/atlas"; +import { GameCard } from "@/pages/game"; -type GameCard = SorceryCard & { id: string }; // for game position type Cards = GameCard[][]; export type GameStateActions = { gridItems: Cards; setGridItems: Dispatch>; }; export const GameBoard = ({ gridItems, setGridItems }: GameStateActions) => { - const { handleDragEnd, handleDragStart, activeId, activeCard } = + const { sensors, handleDragEnd, handleDragStart, activeId, activeCard } = useHandleDrag({ gridItems, setGridItems, @@ -57,6 +56,7 @@ export const GameBoard = ({ gridItems, setGridItems }: GameStateActions) => { onDragStart={handleDragStart} onDragEnd={handleDragEnd} collisionDetection={collision} + sensors={sensors} > {gridItems?.slice(0, 20)?.map((cards, gridIndex) => ( @@ -64,7 +64,7 @@ export const GameBoard = ({ gridItems, setGridItems }: GameStateActions) => { key={"grid-" + gridIndex} id={gridIndex.toString()} gridIndex={gridIndex} - style={{ overflowY: "auto" }} + style={{ overflowY: "auto", overflowX: "clip" }} > { ))} @@ -99,27 +100,55 @@ const SortItemWrapper = ({ card, gridIndex, cardIndex, + ...props }: { card: GameCard; gridIndex: number; cardIndex: number; amountOfCards?: number; -}) => { +} & GameStateActions) => { const [preview, setPreview] = useState(false); - const heightCalc = 90 - Math.min(amountOfCards, 4) * 15; - const height = `${heightCalc}px`; + + const heightCalc = () => { + if (amountOfCards === 1) return 120; + if (amountOfCards === 2) return 75; + if (amountOfCards === 3) return 65; + + return 90 - Math.min(amountOfCards, 4) * 15; + }; + const height = `${heightCalc()}px`; + + const isTapped = card.isTapped; + function toggleTap() { + props.setGridItems(() => { + const newGrid = [...props.gridItems]; + const card = newGrid[gridIndex][cardIndex]; + newGrid[gridIndex][cardIndex] = { + ...card, + isTapped: !card.isTapped, + } as GameCard; + + return newGrid; + }); + } return (
{ + onClick={(e) => { e.preventDefault(); - setPreview(true); + e.stopPropagation(); + toggleTap(); }} onContextMenu={(e) => { e.preventDefault(); setPreview(true); }} - style={{ height: heightCalc + 7 + "px" }} + style={{ + height: heightCalc() + 7 + "px", + transform: isTapped ? "rotate(5deg)" : "", + filter: isTapped ? "saturate(0)" : "", + transition: "all 0.25s ease", + }} > { const [active, setActive] = useState(null); + const pointerSensor = useSensor(PointerSensor, { + activationConstraint: { + distance: 5, + }, + }); + const mouseSensor = useSensor(MouseSensor); + const touchSensor = useSensor(TouchSensor); + const keyboardSensor = useSensor(KeyboardSensor); + + const sensors = useSensors( + pointerSensor, + mouseSensor, + touchSensor, + keyboardSensor, + ); + function handleDragStart(event: DragEndEvent) { setActive(event?.active); } @@ -62,6 +86,7 @@ export const useHandleDrag = ({ } return { + sensors, handleDragEnd, handleDragStart, activeId: active?.id, diff --git a/src/pages/game.tsx b/src/pages/game.tsx index d1efda1..5babb09 100644 --- a/src/pages/game.tsx +++ b/src/pages/game.tsx @@ -5,45 +5,57 @@ import { useState } from "react"; const handCards: GameCard[] = [ { - id: "atlas-02", - img: "atlas_cloud_city.webp", - type: "site", + id: "sorcerer-01", + img: "sorcerer.webp", + type: "avatar", }, +]; + +const deckCards = Array.from({ length: 30 }).map((_, index) => ({ + id: "headless-ab-" + index, + img: "headless_haunt.webp", + type: "minion", +})); + +const mockDeck: GameCard[] = [ { - id: "headless-02", - img: "headless_haunt.webp", + id: "jihad", + img: "jihad.webp", + type: "aura", + }, + { + id: "death_dealer-01", + img: "death_dealer.webp", type: "minion", }, { - id: "headless-03", - img: "headless_haunt.webp", + id: "infernal_legion-01", + img: "infernal_legion.webp", type: "minion", }, { - id: "headless-04", - img: "headless_haunt.webp", + id: "wayfaring_pilgrim-01", + img: "wayfaring_pilgrim.webp", type: "minion", }, ]; -const deckCards = Array.from({ length: 30 }).map((_, index) => ({ - id: "headless-ab-" + index, - img: "headless_haunt.webp", - type: "minion", -})); - const atlasCards = Array.from({ length: 10 }).map((_, index) => ({ id: "atlas-02" + index, - img: "atlas_cloud_city.webp", + img: "arid_desert.webp", type: "site", })); const initCards: GameCard[][] = Array.from({ length: 35 }, () => []); initCards[GRIDS.HAND] = handCards as GameCard[]; -initCards[GRIDS.DECK] = deckCards as GameCard[]; +initCards[GRIDS.DECK] = [...deckCards, ...mockDeck] as GameCard[]; initCards[GRIDS.ATLAS_DECK] = atlasCards as GameCard[]; -export type GameCard = SorceryCard & { id: string }; // for game position +type GameProps = { + id: string; + isTapped?: boolean; +}; +export type GameCard = SorceryCard & GameProps; // for game position export default function GamePage() { const [gridItems, setGridItems] = useState(initCards);