food!
This commit is contained in:
@@ -2,32 +2,42 @@ import { useState, useEffect, useRef } from "react";
|
||||
import type { GameStatus } from "../types";
|
||||
import type { UseRendererType } from "./useRenderer";
|
||||
import type { UseSnakeType } from "./useSnake";
|
||||
import type { UseFoodType } from "./useFood";
|
||||
|
||||
const INITIAL_SPEED = 200;
|
||||
const FRAMES_PER_SECOND = 5;
|
||||
|
||||
export function useGameStatus(
|
||||
rendererManager: UseRendererType,
|
||||
snakeManager: UseSnakeType
|
||||
snakeManager: UseSnakeType,
|
||||
foodManager: UseFoodType
|
||||
) {
|
||||
const { containerRef } = rendererManager;
|
||||
const { initSnake, clearSnake } = snakeManager;
|
||||
const { initSnake, clearSnake, snakeBodyRef } = snakeManager;
|
||||
const { spawnFood, clearFood } = foodManager;
|
||||
const [gameStatus, setGameStatus] = useState<GameStatus>("waiting");
|
||||
const gameLoopRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||
const [score, setScore] = useState(0);
|
||||
const gameLoopRef = useRef<number | null>(null);
|
||||
const lastUpdateRef = useRef<number>(0);
|
||||
const snakeManagerRef = useRef(snakeManager);
|
||||
const foodManagerRef = useRef(foodManager);
|
||||
|
||||
snakeManagerRef.current = snakeManager;
|
||||
foodManagerRef.current = foodManager;
|
||||
|
||||
const startGame = () => {
|
||||
initSnake();
|
||||
spawnFood(snakeBodyRef.current, 3);
|
||||
setScore(0);
|
||||
setGameStatus("started");
|
||||
};
|
||||
|
||||
const stopGame = () => {
|
||||
if (gameLoopRef.current) {
|
||||
clearInterval(gameLoopRef.current);
|
||||
cancelAnimationFrame(gameLoopRef.current);
|
||||
gameLoopRef.current = null;
|
||||
}
|
||||
clearSnake();
|
||||
clearFood();
|
||||
setGameStatus("waiting");
|
||||
const container = containerRef.current;
|
||||
container?.querySelectorAll(".snake-head, .snake-body, .snake-tail").forEach((el) => {
|
||||
@@ -39,20 +49,50 @@ export function useGameStatus(
|
||||
console.log("useGameStatus effect - gameStatus:", gameStatus);
|
||||
if (gameStatus === "started") {
|
||||
console.log("Starting game loop");
|
||||
gameLoopRef.current = setInterval(() => {
|
||||
console.log("Game loop tick");
|
||||
const result = snakeManagerRef.current.moveSnake();
|
||||
console.log("Move result:", result);
|
||||
|
||||
if (result === "wall-collision") {
|
||||
setGameStatus("game-over");
|
||||
|
||||
let shouldGrow = false;
|
||||
const msPerFrame = 1000 / FRAMES_PER_SECOND;
|
||||
lastUpdateRef.current = performance.now();
|
||||
|
||||
const gameLoop = (timestamp: number) => {
|
||||
const elapsed = timestamp - lastUpdateRef.current;
|
||||
|
||||
if (elapsed >= msPerFrame) {
|
||||
console.log("Game loop tick");
|
||||
const result = snakeManagerRef.current.moveSnake(shouldGrow);
|
||||
console.log("Move result:", result);
|
||||
|
||||
shouldGrow = false;
|
||||
|
||||
if (result === "wall-collision") {
|
||||
setGameStatus("game-over");
|
||||
return;
|
||||
}
|
||||
|
||||
const head = snakeManagerRef.current.snakeBodyRef.current[0];
|
||||
if (head && foodManagerRef.current.checkFoodCollision(head)) {
|
||||
console.log("Food eaten!");
|
||||
foodManagerRef.current.removeFood(head);
|
||||
shouldGrow = true;
|
||||
setScore((prev) => prev + 1);
|
||||
foodManagerRef.current.spawnFood(
|
||||
snakeManagerRef.current.snakeBodyRef.current,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
lastUpdateRef.current = timestamp;
|
||||
}
|
||||
}, INITIAL_SPEED);
|
||||
|
||||
gameLoopRef.current = requestAnimationFrame(gameLoop);
|
||||
};
|
||||
|
||||
gameLoopRef.current = requestAnimationFrame(gameLoop);
|
||||
|
||||
return () => {
|
||||
console.log("Cleaning up game loop");
|
||||
if (gameLoopRef.current) {
|
||||
clearInterval(gameLoopRef.current);
|
||||
cancelAnimationFrame(gameLoopRef.current);
|
||||
gameLoopRef.current = null;
|
||||
}
|
||||
};
|
||||
@@ -62,7 +102,7 @@ export function useGameStatus(
|
||||
useEffect(() => {
|
||||
if (gameStatus === "game-over") {
|
||||
if (gameLoopRef.current) {
|
||||
clearInterval(gameLoopRef.current);
|
||||
cancelAnimationFrame(gameLoopRef.current);
|
||||
gameLoopRef.current = null;
|
||||
}
|
||||
}
|
||||
@@ -73,6 +113,7 @@ export function useGameStatus(
|
||||
setGameStatus,
|
||||
startGame,
|
||||
stopGame,
|
||||
score,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user