주사위판 배치 그리기 일부 구현.
This commit is contained in:
77
app/game/diceplane.tsx
Normal file
77
app/game/diceplane.tsx
Normal file
@@ -0,0 +1,77 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
type PlaneCell = { id: number; x: number; y: number; type: string };
|
||||
|
||||
const PLANE_SIZE = { width: 9, height: 7 } as const;
|
||||
|
||||
const CELL_TYPES = ['한잔', '안주', '모두한잔', '두잔', '벌칙1', '벌칙2'] as const;
|
||||
|
||||
function randomType() {
|
||||
return CELL_TYPES[Math.floor(Math.random() * CELL_TYPES.length)];
|
||||
}
|
||||
|
||||
/** 시계방향 둘레 칸. 모서리는 한 번만 넣어서 9x7 기준 28칸이 된다. */
|
||||
function buildPerimeter(width: number, height: number): PlaneCell[] {
|
||||
const cells: PlaneCell[] = [];
|
||||
let id = 0;
|
||||
|
||||
for (let x = 0; x < width; x++) {
|
||||
cells.push({ id: id++, x, y: 0, type: randomType() });
|
||||
}
|
||||
for (let y = 1; y < height; y++) {
|
||||
cells.push({ id: id++, x: width - 1, y, type: randomType() });
|
||||
}
|
||||
for (let x = width - 2; x >= 0; x--) {
|
||||
cells.push({ id: id++, x, y: height - 1, type: randomType() });
|
||||
}
|
||||
for (let y = height - 2; y >= 1; y--) {
|
||||
cells.push({ id: id++, x: 0, y, type: randomType() });
|
||||
}
|
||||
|
||||
return cells;
|
||||
}
|
||||
|
||||
export default function DicePlane() {
|
||||
const [dicePlaneArray] = useState(() =>
|
||||
buildPerimeter(PLANE_SIZE.width, PLANE_SIZE.height),
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: `repeat(${PLANE_SIZE.width}, minmax(0, 1fr))`,
|
||||
gridTemplateRows: `repeat(${PLANE_SIZE.height}, minmax(0, 1fr))`,
|
||||
gap: 'clamp(6px, 1vw, 12px)',
|
||||
padding: 'clamp(8px, 1.2vw, 16px)',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
boxSizing: 'border-box',
|
||||
}}
|
||||
>
|
||||
{dicePlaneArray.map((plane) => (
|
||||
<div
|
||||
key={plane.id}
|
||||
style={{
|
||||
gridColumn: plane.x + 1,
|
||||
gridRow: plane.y + 1,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: '#e11d48',
|
||||
color: 'white',
|
||||
borderRadius: 8,
|
||||
fontSize: 'clamp(11px, 1.6vw, 16px)',
|
||||
fontWeight: 600,
|
||||
textAlign: 'center',
|
||||
padding: 4,
|
||||
}}
|
||||
>
|
||||
{plane.type}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
12
app/game/page.tsx
Normal file
12
app/game/page.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import DicePlane from './diceplane';
|
||||
|
||||
export default function GamePage() {
|
||||
return (
|
||||
<div className="relative h-screen w-screen overflow-hidden">
|
||||
<DicePlane />
|
||||
<h1 className="pointer-events-none absolute inset-0 flex items-center justify-center text-4xl font-bold">
|
||||
Game
|
||||
</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user