feat: add initialSnakeSize and initialFoodCount to GameOptions
- New option: initialSnakeSize (defaults to 3)
- New option: initialFoodCount (defaults to 1)
- Snake spawns with configurable size
- Initial food count is configurable
- Example: useGame({ initialSnakeSize: 5, initialFoodCount: 2 })
This commit is contained in:
@@ -35,6 +35,8 @@ export type GameOptions = {
|
||||
startingLevel?: number;
|
||||
foodsPerLevel?: number;
|
||||
maxLevel?: number;
|
||||
initialSnakeSize?: number;
|
||||
initialFoodCount?: number;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -2,11 +2,17 @@ import { useRef, useState } from "react";
|
||||
import type { Direction, SnakeBody, Position } from "../types";
|
||||
import type { UseBoardType } from "../useBoard";
|
||||
|
||||
export type UseCursorParams = {
|
||||
initialSnakeSize?: number;
|
||||
};
|
||||
|
||||
export function useCursor(
|
||||
cols: number,
|
||||
rows: number,
|
||||
boardManager: UseBoardType
|
||||
boardManager: UseBoardType,
|
||||
params?: UseCursorParams
|
||||
) {
|
||||
const initialSnakeSize = params?.initialSnakeSize ?? 3;
|
||||
const { containerRef } = boardManager;
|
||||
const [snakeBody, setSnakeBody] = useState<SnakeBody>([]);
|
||||
const snakeBodyRef = useRef<SnakeBody>([]);
|
||||
@@ -19,11 +25,10 @@ export function useCursor(
|
||||
const centerR = Math.floor(rows / 2);
|
||||
const centerC = Math.floor(cols / 2);
|
||||
|
||||
const initialBody: SnakeBody = [
|
||||
{ r: centerR, c: centerC },
|
||||
{ r: centerR + 1, c: centerC },
|
||||
{ r: centerR + 2, c: centerC },
|
||||
];
|
||||
const initialBody: SnakeBody = [];
|
||||
for (let i = 0; i < initialSnakeSize; i++) {
|
||||
initialBody.push({ r: centerR + i, c: centerC });
|
||||
}
|
||||
|
||||
setSnakeBody(initialBody);
|
||||
snakeBodyRef.current = initialBody;
|
||||
|
||||
@@ -8,17 +8,17 @@ import { useKeyBindings, type UseKeyBindingsType } from "./useKeyBindings";
|
||||
import { useScore } from "../useScore";
|
||||
|
||||
export function useGame(options?: GameOptions, platformHook?: unknown): GameManager {
|
||||
const { cols = 30, rows = 20, startingLevel, foodsPerLevel, maxLevel } = options ?? {};
|
||||
const { cols = 30, rows = 20, startingLevel, foodsPerLevel, maxLevel, initialSnakeSize, initialFoodCount } = options ?? {};
|
||||
|
||||
const boardManager = useBoard();
|
||||
const { containerRef, renderBoard } = boardManager;
|
||||
|
||||
const snakeManager = useCursor(cols, rows, boardManager);
|
||||
const snakeManager = useCursor(cols, rows, boardManager, { initialSnakeSize });
|
||||
const { changeDirection } = snakeManager;
|
||||
|
||||
const foodManager = useFood(cols, rows, boardManager);
|
||||
|
||||
const gameManager = useGameStatus(boardManager, snakeManager, foodManager, { startingLevel, foodsPerLevel, maxLevel });
|
||||
const gameManager = useGameStatus(boardManager, snakeManager, foodManager, { startingLevel, foodsPerLevel, maxLevel, initialFoodCount });
|
||||
const { gameStatus, setGameStatus, startGame, quitGame, togglePause, score, level } = gameManager;
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -8,6 +8,7 @@ export type UseGameStatusParams = {
|
||||
startingLevel?: number;
|
||||
foodsPerLevel?: number;
|
||||
maxLevel?: number;
|
||||
initialFoodCount?: number;
|
||||
};
|
||||
|
||||
export function useGameStatus(
|
||||
@@ -19,6 +20,7 @@ export function useGameStatus(
|
||||
const startingLevel = params?.startingLevel ?? 1;
|
||||
const foodsPerLevel = params?.foodsPerLevel ?? 10;
|
||||
const maxLevel = params?.maxLevel ?? 25;
|
||||
const initialFoodCount = params?.initialFoodCount ?? 1;
|
||||
const { containerRef } = boardManager;
|
||||
const { initSnake, clearSnake, snakeBodyRef } = snakeManager;
|
||||
const { spawnFood, clearFood } = foodManager;
|
||||
@@ -38,7 +40,7 @@ export function useGameStatus(
|
||||
|
||||
const startGame = () => {
|
||||
initSnake();
|
||||
spawnFood(snakeBodyRef.current, 3);
|
||||
spawnFood(snakeBodyRef.current, initialFoodCount);
|
||||
setScore(0);
|
||||
setLevel(startingLevel);
|
||||
levelRef.current = startingLevel;
|
||||
|
||||
Reference in New Issue
Block a user