Compare commits
2 Commits
0124b69440
...
0dc0a9ce62
| Author | SHA1 | Date | |
|---|---|---|---|
| 0dc0a9ce62 | |||
| 5f05eb4adf |
BIN
assets/sources/cards.png
LFS
Normal file
BIN
assets/sources/cards.png
LFS
Normal file
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 664 B After Width: | Height: | Size: 5.3 KiB |
@@ -23,6 +23,10 @@ body::before {
|
|||||||
background: radial-gradient(rgb(24, 82, 65), rgb(1, 42, 16));
|
background: radial-gradient(rgb(24, 82, 65), rgb(1, 42, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hand {
|
||||||
|
background: radial-gradient(rgb(24, 70, 82), rgb(1, 42, 41));
|
||||||
|
}
|
||||||
|
|
||||||
.full {
|
.full {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Component, createResource, JSX, Suspense } from "solid-js";
|
import { Component, createResource, JSX, Suspense } from "solid-js";
|
||||||
import { Card } from "../types/cards";
|
import { Card } from "../types/cards";
|
||||||
|
import { Clickable, Stylable } from "./toolbox";
|
||||||
|
|
||||||
const cardToSvgFilename = (card: Card) => {
|
const cardToSvgFilename = (card: Card) => {
|
||||||
if (card.kind == "joker") {
|
if (card.kind == "joker") {
|
||||||
@@ -30,6 +31,7 @@ export default ((props) => {
|
|||||||
return (
|
return (
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<img
|
<img
|
||||||
|
onClick={props.onClick}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
class={props.class}
|
class={props.class}
|
||||||
style={{
|
style={{
|
||||||
@@ -41,9 +43,10 @@ export default ((props) => {
|
|||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
}) satisfies Component<{
|
}) satisfies Component<
|
||||||
class?: string;
|
{
|
||||||
style?: JSX.CSSProperties;
|
card: Card;
|
||||||
card: Card;
|
face?: "up" | "down";
|
||||||
face?: "up" | "down";
|
} & Stylable &
|
||||||
}>;
|
Clickable
|
||||||
|
>;
|
||||||
|
|||||||
@@ -2,32 +2,35 @@ import { createContext, JSX } from "solid-js";
|
|||||||
import Card from "./Card";
|
import Card from "./Card";
|
||||||
import Hand from "./Hand";
|
import Hand from "./Hand";
|
||||||
import Pile from "./Pile";
|
import Pile from "./Pile";
|
||||||
import { newDeck, shuffle, Hand as THand } from "../types/cards";
|
import { GameState, newDeck, shuffle, Hand as THand } from "../types/cards";
|
||||||
import { createStore, produce } from "solid-js/store";
|
import { createStore, produce, SetStoreFunction, Store } from "solid-js/store";
|
||||||
|
|
||||||
const GameContext = createContext();
|
export const GameContext = createContext<{
|
||||||
|
gameState: Store<GameState>;
|
||||||
|
setGameState: SetStoreFunction<GameState>;
|
||||||
|
}>();
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [gameState, setGameState] = createStore({
|
const [gameState, setGameState] = createStore<GameState>({
|
||||||
pile: shuffle(newDeck()),
|
deck: shuffle(newDeck()),
|
||||||
hand: [] as THand,
|
hand: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GameContext.Provider value={{ gameState, setGameState }}>
|
<GameContext.Provider value={{ gameState, setGameState }}>
|
||||||
<div
|
<div
|
||||||
onClick={() => {}}
|
onClick={() => {}}
|
||||||
class="full column"
|
class="full column center"
|
||||||
style={{ "row-gap": "20px", "font-size": "32px" }}
|
style={{ "row-gap": "20px", "font-size": "32px" }}
|
||||||
>
|
>
|
||||||
<div class="full center">
|
<div class="full center">
|
||||||
<Pile
|
<Pile
|
||||||
pile={gameState.pile}
|
pile={gameState.deck}
|
||||||
style={{ cursor: "pointer" }}
|
style={{ cursor: "pointer" }}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setGameState(
|
setGameState(
|
||||||
produce((state) => {
|
produce((state) => {
|
||||||
state.hand.push(state.pile.pop()!);
|
state.hand.push(state.deck.pop()!);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
import { Component, For } from "solid-js";
|
import { Component, For, useContext } from "solid-js";
|
||||||
import Card from "./Card";
|
import Card from "./Card";
|
||||||
import { Hand } from "../types/cards";
|
import { Hand } from "../types/cards";
|
||||||
|
import { GameContext } from "./Game";
|
||||||
|
import { produce } from "solid-js/store";
|
||||||
|
|
||||||
export default ((props) => {
|
export default ((props) => {
|
||||||
|
const { setGameState } = useContext(GameContext)!;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
class="hand"
|
||||||
style={{
|
style={{
|
||||||
|
"min-width": "100px",
|
||||||
|
width: "fit-content",
|
||||||
|
"max-width": "80%",
|
||||||
border: "2px dashed white",
|
border: "2px dashed white",
|
||||||
"border-radius": "12px",
|
"border-radius": "12px",
|
||||||
margin: "10px",
|
margin: "10px",
|
||||||
@@ -18,7 +26,30 @@ export default ((props) => {
|
|||||||
gap: "5px",
|
gap: "5px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<For each={props.hand}>{(card) => <Card card={card} />}</For>
|
<For each={props.hand}>
|
||||||
|
{(card) => (
|
||||||
|
<Card
|
||||||
|
card={card}
|
||||||
|
style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
}}
|
||||||
|
onClick={() =>
|
||||||
|
setGameState(
|
||||||
|
produce((state) => {
|
||||||
|
const index = state.hand.indexOf(card);
|
||||||
|
console.log(index);
|
||||||
|
state.deck.push(
|
||||||
|
state.hand.splice(
|
||||||
|
props.hand.indexOf(card),
|
||||||
|
1
|
||||||
|
)[0]!
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}) satisfies Component<{ hand: Hand }>;
|
}) satisfies Component<{ hand: Hand }>;
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
import { Component, For, JSX } from "solid-js";
|
import { Component, For, JSX } from "solid-js";
|
||||||
import Card from "./Card";
|
import Card from "./Card";
|
||||||
import { Pile } from "../types/cards";
|
import { Pile } from "../types/cards";
|
||||||
|
import { type ComponentProps } from "solid-js";
|
||||||
|
import { Clickable, Stylable } from "./toolbox";
|
||||||
|
|
||||||
export default ((props) => {
|
export default ((props) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
class="center"
|
{...props}
|
||||||
style={{ width: "200px", height: "400px", ...props.style }}
|
class={`center ${props.class ?? ""}}`.trim()}
|
||||||
|
style={{
|
||||||
|
width: "200px",
|
||||||
|
height: "400px",
|
||||||
|
...(props.style as JSX.CSSProperties),
|
||||||
|
}}
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
>
|
>
|
||||||
<For each={props.pile}>
|
<For each={props.pile}>
|
||||||
@@ -16,14 +23,14 @@ export default ((props) => {
|
|||||||
face="down"
|
face="down"
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
transform: `translate(${i() * 0.8}px, ${
|
transform: `translate(${i() * 0.5}px, ${
|
||||||
-i() * 0.4
|
i() * 0.2
|
||||||
}px)`,
|
}px)`,
|
||||||
"z-index": 100 - i(),
|
// "z-index": 100 - i(),
|
||||||
border: `0.1px solid rgb(${
|
border: `0.1px solid rgb(${
|
||||||
60 - i() + Math.random() * 10
|
10 + i() + Math.random() * 50
|
||||||
}, ${60 - i() + Math.random() * 10}, ${
|
}, ${10 + i() + Math.random() * 50}, ${
|
||||||
60 - i() + Math.random() * 10
|
10 + i() + Math.random() * 50
|
||||||
});`,
|
});`,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -31,14 +38,9 @@ export default ((props) => {
|
|||||||
</For>
|
</For>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}) satisfies Component<{
|
}) satisfies Component<
|
||||||
pile: Pile;
|
{
|
||||||
style?: JSX.CSSProperties;
|
pile: Pile;
|
||||||
onClick?:
|
} & Stylable &
|
||||||
| JSX.EventHandlerUnion<
|
Clickable
|
||||||
HTMLDivElement,
|
>;
|
||||||
MouseEvent,
|
|
||||||
JSX.EventHandler<HTMLDivElement, MouseEvent>
|
|
||||||
>
|
|
||||||
| undefined;
|
|
||||||
}>;
|
|
||||||
|
|||||||
16
src/components/toolbox.tsx
Normal file
16
src/components/toolbox.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { JSX } from "solid-js";
|
||||||
|
|
||||||
|
export type Stylable = {
|
||||||
|
class?: string;
|
||||||
|
style?: JSX.CSSProperties;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Clickable = {
|
||||||
|
onClick?:
|
||||||
|
| JSX.EventHandlerUnion<
|
||||||
|
HTMLDivElement,
|
||||||
|
MouseEvent,
|
||||||
|
JSX.EventHandler<HTMLDivElement, MouseEvent>
|
||||||
|
>
|
||||||
|
| undefined;
|
||||||
|
};
|
||||||
@@ -55,3 +55,8 @@ export const shuffle = (cards: Card[]) => {
|
|||||||
}
|
}
|
||||||
return cards;
|
return cards;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type GameState = {
|
||||||
|
deck: Pile;
|
||||||
|
hand: Hand;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user