feat: add maxLevel to GameOptions with default of 25

- New option: maxLevel (defaults to 25)
- Once a player reaches maxLevel, levels no longer progress
- Prevents unlimited level scaling and FPS increases
- Example: useGame({ maxLevel: 10 })
This commit is contained in:
2025-10-31 00:28:29 +00:00
parent 520a640ea0
commit b82bef56e5
4 changed files with 10 additions and 6 deletions
+2 -1
View File
@@ -3,7 +3,8 @@ import "@vimazing/vim-snake/game.css";
import { useKeyBindings } from "./useKeyBindings";
function App() {
const { containerRef, gameStatus, scoreManager, keyLog, score, level } = useGame({}, useKeyBindings);
const gameManager = useGame({ startingLevel: 10 }, useKeyBindings);
const { containerRef, gameStatus, scoreManager, score, level } = gameManager;
const formatTime = (ms: number) => {
const seconds = Math.floor(ms / 1000);
+1
View File
@@ -34,6 +34,7 @@ export type GameOptions = {
timeLimit?: number;
startingLevel?: number;
foodsPerLevel?: number;
maxLevel?: number;
};
// ============================================================================
+2 -2
View File
@@ -8,7 +8,7 @@ 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 } = options ?? {};
const { cols = 30, rows = 20, startingLevel, foodsPerLevel, maxLevel } = options ?? {};
const boardManager = useBoard();
const { containerRef, renderBoard } = boardManager;
@@ -18,7 +18,7 @@ export function useGame(options?: GameOptions, platformHook?: unknown): GameMana
const foodManager = useFood(cols, rows, boardManager);
const gameManager = useGameStatus(boardManager, snakeManager, foodManager, { startingLevel, foodsPerLevel });
const gameManager = useGameStatus(boardManager, snakeManager, foodManager, { startingLevel, foodsPerLevel, maxLevel });
const { gameStatus, setGameStatus, startGame, quitGame, togglePause, score, level } = gameManager;
useEffect(() => {
+3 -1
View File
@@ -7,6 +7,7 @@ import type { UseFoodType } from "../useGame/useFood";
export type UseGameStatusParams = {
startingLevel?: number;
foodsPerLevel?: number;
maxLevel?: number;
};
export function useGameStatus(
@@ -17,6 +18,7 @@ export function useGameStatus(
) {
const startingLevel = params?.startingLevel ?? 1;
const foodsPerLevel = params?.foodsPerLevel ?? 10;
const maxLevel = params?.maxLevel ?? 25;
const { containerRef } = boardManager;
const { initSnake, clearSnake, snakeBodyRef } = snakeManager;
const { spawnFood, clearFood } = foodManager;
@@ -99,7 +101,7 @@ export function useGameStatus(
const pointsToAdd = levelRef.current;
// Update level OUTSIDE of setScore to avoid multiple triggers
if (willLevelUp) {
if (willLevelUp && levelRef.current < maxLevel) {
const newLevel = levelRef.current + 1;
levelRef.current = newLevel;
setLevel(newLevel);