snake moving, changing directions, wall collision working
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
import { useState } from "react";
|
import { useState, useEffect, useRef } from "react";
|
||||||
import type { GameStatus } from "../types";
|
import type { GameStatus } from "../types";
|
||||||
import type { UseRendererType } from "./useRenderer";
|
import type { UseRendererType } from "./useRenderer";
|
||||||
import type { UseSnakeType } from "./useSnake";
|
import type { UseSnakeType } from "./useSnake";
|
||||||
|
|
||||||
|
const INITIAL_SPEED = 200;
|
||||||
|
|
||||||
export function useGameStatus(
|
export function useGameStatus(
|
||||||
rendererManager: UseRendererType,
|
rendererManager: UseRendererType,
|
||||||
snakeManager: UseSnakeType
|
snakeManager: UseSnakeType
|
||||||
@@ -10,6 +12,10 @@ export function useGameStatus(
|
|||||||
const { containerRef } = rendererManager;
|
const { containerRef } = rendererManager;
|
||||||
const { initSnake, clearSnake } = snakeManager;
|
const { initSnake, clearSnake } = snakeManager;
|
||||||
const [gameStatus, setGameStatus] = useState<GameStatus>("waiting");
|
const [gameStatus, setGameStatus] = useState<GameStatus>("waiting");
|
||||||
|
const gameLoopRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||||
|
const snakeManagerRef = useRef(snakeManager);
|
||||||
|
|
||||||
|
snakeManagerRef.current = snakeManager;
|
||||||
|
|
||||||
const startGame = () => {
|
const startGame = () => {
|
||||||
initSnake();
|
initSnake();
|
||||||
@@ -17,6 +23,10 @@ export function useGameStatus(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const stopGame = () => {
|
const stopGame = () => {
|
||||||
|
if (gameLoopRef.current) {
|
||||||
|
clearInterval(gameLoopRef.current);
|
||||||
|
gameLoopRef.current = null;
|
||||||
|
}
|
||||||
clearSnake();
|
clearSnake();
|
||||||
setGameStatus("waiting");
|
setGameStatus("waiting");
|
||||||
const container = containerRef.current;
|
const container = containerRef.current;
|
||||||
@@ -25,6 +35,39 @@ export function useGameStatus(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}, INITIAL_SPEED);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
console.log("Cleaning up game loop");
|
||||||
|
if (gameLoopRef.current) {
|
||||||
|
clearInterval(gameLoopRef.current);
|
||||||
|
gameLoopRef.current = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [gameStatus]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (gameStatus === "game-over") {
|
||||||
|
if (gameLoopRef.current) {
|
||||||
|
clearInterval(gameLoopRef.current);
|
||||||
|
gameLoopRef.current = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [gameStatus]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
gameStatus,
|
gameStatus,
|
||||||
setGameStatus,
|
setGameStatus,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export function useSnake(
|
|||||||
) {
|
) {
|
||||||
const { containerRef } = rendererManager;
|
const { containerRef } = rendererManager;
|
||||||
const [snakeBody, setSnakeBody] = useState<SnakeBody>([]);
|
const [snakeBody, setSnakeBody] = useState<SnakeBody>([]);
|
||||||
|
const snakeBodyRef = useRef<SnakeBody>([]);
|
||||||
const [direction, setDirection] = useState<Direction>("up");
|
const [direction, setDirection] = useState<Direction>("up");
|
||||||
const directionRef = useRef<Direction>("up");
|
const directionRef = useRef<Direction>("up");
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ export function useSnake(
|
|||||||
];
|
];
|
||||||
|
|
||||||
setSnakeBody(initialBody);
|
setSnakeBody(initialBody);
|
||||||
|
snakeBodyRef.current = initialBody;
|
||||||
setDirection("up");
|
setDirection("up");
|
||||||
directionRef.current = "up";
|
directionRef.current = "up";
|
||||||
renderSnake(initialBody);
|
renderSnake(initialBody);
|
||||||
@@ -30,6 +32,7 @@ export function useSnake(
|
|||||||
|
|
||||||
const clearSnake = () => {
|
const clearSnake = () => {
|
||||||
setSnakeBody([]);
|
setSnakeBody([]);
|
||||||
|
snakeBodyRef.current = [];
|
||||||
setDirection("up");
|
setDirection("up");
|
||||||
directionRef.current = "up";
|
directionRef.current = "up";
|
||||||
};
|
};
|
||||||
@@ -66,13 +69,54 @@ export function useSnake(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const moveSnake = (): "continue" | "wall-collision" | "self-collision" => {
|
||||||
|
const body = snakeBodyRef.current;
|
||||||
|
if (body.length === 0) return "continue";
|
||||||
|
|
||||||
|
const head = body[0];
|
||||||
|
const dir = directionRef.current;
|
||||||
|
|
||||||
|
let newR = head.r;
|
||||||
|
let newC = head.c;
|
||||||
|
|
||||||
|
switch (dir) {
|
||||||
|
case "up":
|
||||||
|
newR -= 1;
|
||||||
|
break;
|
||||||
|
case "down":
|
||||||
|
newR += 1;
|
||||||
|
break;
|
||||||
|
case "left":
|
||||||
|
newC -= 1;
|
||||||
|
break;
|
||||||
|
case "right":
|
||||||
|
newC += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newR < 0 || newR >= rows || newC < 0 || newC >= cols) {
|
||||||
|
return "wall-collision";
|
||||||
|
}
|
||||||
|
|
||||||
|
const newHead = { r: newR, c: newC };
|
||||||
|
const newBody = [newHead, ...body.slice(0, -1)];
|
||||||
|
|
||||||
|
setSnakeBody(newBody);
|
||||||
|
snakeBodyRef.current = newBody;
|
||||||
|
renderSnake(newBody);
|
||||||
|
|
||||||
|
return "continue";
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
snakeBody,
|
snakeBody,
|
||||||
|
snakeBodyRef,
|
||||||
direction,
|
direction,
|
||||||
directionRef,
|
directionRef,
|
||||||
initSnake,
|
initSnake,
|
||||||
clearSnake,
|
clearSnake,
|
||||||
changeDirection,
|
changeDirection,
|
||||||
|
moveSnake,
|
||||||
renderSnake,
|
renderSnake,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user