diff --git a/app/globals.css b/app/globals.css
index 875c01e..b8ac6e2 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -4,7 +4,7 @@
:root {
--foreground-rgb: 0, 0, 0;
- --background-start-rgb: 214, 219, 220;
+ --background-start-rgb: 255, 255, 255;
--background-end-rgb: 255, 255, 255;
}
@@ -24,6 +24,43 @@ body {
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
+ background: white;
+}
+
+.crt {
+ background: linear-gradient(to top, #000000, #000000, #333333, #333333);
+ background-size: cover;
+ background-size: 100% 2px;
+
+ color: #00ff00;
+ font-size: 50px;
+ /* text-align: center; */
+ text-shadow: 0 0 10px #00ff00;
+
+ filter: blur(.8px);
+ border-radius: 20px;
+}
+
+.red-bot {
+ color: rgb(235, 90, 90);
+}
+
+.blue-bot {
+ color: rgb(94, 158, 217);
+}
+
+@media screen{
+ .crt {
+ animation: scanlines infinite 55s linear ;
+ }
+}
+@keyframes scanlines {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 0 -10px;
+ }
}
@layer utilities {
diff --git a/app/maze.tsx b/app/maze.tsx
index 9ebd218..c3f4836 100644
--- a/app/maze.tsx
+++ b/app/maze.tsx
@@ -1,14 +1,18 @@
"use client"
import React, {
- useEffect
+ useEffect,
+ useMemo,
+ useRef,
+ useState
} from "react";
import anime from 'animejs/lib/anime.es.js';
+import { AnimatePresence, motion } from "framer-motion"
type Pos = [number, number];
-const cellSize = 32; // Size of each cell in the SVG
+const cellSize = 26; // Size of each cell in the SVG
const offset = 0.2 * cellSize; // Offset for the outline
let radius = 0.5 * cellSize - offset;
let radius_inner = offset;
@@ -235,12 +239,89 @@ const createPath = (cluster: Pos[]) => {
return paths;
});
- console.log(pathCommands);
return pathCommands.join(" ");
};
+function usePrevious(value: any) {
+ const ref = useRef();
+ useEffect(() => {
+ ref.current = value; //assign the value of ref to the argument
+ }, [value]); //this code will run when the value of 'value' changes
+ return ref.current; //in the end, return the current ref value.
+}
-function Bot({ position, color, width }: { position: Pos, color: string, width: number }) {
+function Food({ position, color }: { position: Pos, color: string }) {
+ const [x, y] = position;
+ return (
+
+ )
+}
+
+// // from https://www.30secondsofcode.org/react/s/use-interval-explained/
+// const useInterval = (callback: any, delay: number) => {
+// const savedCallback = React.useRef();
+
+// React.useEffect(() => {
+// savedCallback.current = callback;
+// }, [callback]);
+
+// React.useEffect(() => {
+// function tick() {
+// savedCallback?.current();
+// }
+// if (delay !== null) {
+// let id = setInterval(tick, delay);
+// return () => clearInterval(id);
+// }
+// }, [delay]);
+// };
+
+function Pacman({ direction, mouthAngle, color }: { direction: number, mouthAngle: number, color: string }) {
+
+ const pacmanPath = (angle: number) => {
+ const angle_rad = angle / 180 * Math.PI;
+ const radius = 8;
+ const x = radius * Math.cos(angle_rad / 2);
+ const y = radius * Math.sin(angle_rad / 2);
+ return `M 0,0 L ${x},${-y} A ${radius},${radius} 0 1 0 ${x},${y} Z`;
+ }
+
+ return (
+
+
+
+ )
+}
+
+function Bot({ position, color, say, width, turnsAgo }: { position: Pos, color: string, say: string, width: number, turnsAgo: number }) {
const leftSide = position[0] < width / 2;
const inHomezone = () => {
switch (color) {
@@ -251,6 +332,24 @@ function Bot({ position, color, width }: { position: Pos, color: string, width:
return !leftSide;
}
}
+ const [direction, setDirection] = useState(leftSide ? 0 : 180);
+ const oldPosition = usePrevious(position);
+
+ // const [mouthAngleTL, setMouthAngleTL] = useState(0);
+ // useInterval(() => setMouthAngleTL(mouthAngleTL + 0.08), 10);
+
+ const mouthAngle = 50; // Math.abs(50 * Math.sin(mouthAngleTL));
+
+ useEffect(() => {
+ if (oldPosition) {
+ const dx = position[0] - oldPosition[0];
+ const dy = position[1] - oldPosition[1];
+ if (dx < 0) setDirection(180);
+ else if (dy < 0) setDirection(270);
+ else if (dx > 0) setDirection(0);
+ else if (dy > 0) setDirection(90);
+ }
+ }, [oldPosition]);
useEffect(() => {
anime.timeline()
@@ -269,27 +368,121 @@ function Bot({ position, color, width }: { position: Pos, color: string, width:
}, []);
return (
-
+
+ {
+ inHomezone() ? (
+
+
+{/* Round path: // M -8 0 C -8 -4.4 -4.4 -8 0 -8 C 4.4 -8 8 -4.4 8 0 L 8 8 C 8 9 6.6667 5.6 6 5.6 S 4.6667 8.19 4 8.19 S 2.6667 5.6 2 5.6 S 0.6667 8.19 0 8.19 S -1.3333 5.6 -2 5.6 S -3.3333 8.19 -4 8.19 S -5.3333 5.6 -6 5.6 S -8 9 -8 8 C -8 5.3333 -8 2.6667 -8 0 Z */}
+{/* Straight path: // M -8 0 C -8 -4.4 -4.4 -8 0 -8 C 4.4 -8 8 -4.4 8 0 L 8 8 L 6 5.6 L 4 8 L 2 5.6 L 0 8 L -2 5.6 L -4 8 L -6 5.6 L -8 8 L -8 0 Z */}
+
+
+
+
+
+
+ ) : (
+
+ )
+ }
+ {say}
+ {say}
+
)
}
+function Walls({ shape, walls }: { shape: Pos, walls: Pos[] }) {
+ const clusters = useMemo(() => findClusters(shape, walls), [shape, walls]);
+ const [width, height] = shape;
-function Maze({ game_uuid, shape, walls, food, a, b, x, y, whowins, gameover }:
+ return (
+
+
+
+
+ {walls.map(([x, y], index) => (
+
+ ))}
+ {clusters.map((cluster, index) => (
+
+ ))}
+
+ );
+}
+
+
+function Maze({ game_uuid, shape, walls, food, bots, team_names, say, whowins, gameover, round, turn }:
{
game_uuid: string,
shape: Pos,
walls: Pos[],
food: Pos[],
- a: Pos,
- b: Pos,
- x: Pos,
- y: Pos,
+ bots: [Pos, Pos, Pos, Pos],
+ team_names: [string, string],
+ say: [string, string, string, string],
whowins: number | null,
- gameover: boolean
+ gameover: boolean,
+ round: number,
+ turn: number,
}
) {
const [width, height] = shape;
- const clusters = findClusters(shape, walls);
+ const [a, x, b, y] = bots;
+ const [sayA, sayX, sayB, sayY] = say;
useEffect(() => {
if (game_uuid) {
@@ -310,6 +503,12 @@ function Maze({ game_uuid, shape, walls, food, a, b, x, y, whowins, gameover }:
easing: 'linear',
duration: 2000
}, 2000)
+ .add({
+ targets: '#mazebox #maze path',
+ strokeWidth: 0,
+ easing: 'linear',
+ duration: 2000
+ }, 4000)
.add({
targets: '#mazebox .foodblue',
opacity: [0, 1],
@@ -333,6 +532,12 @@ function Maze({ game_uuid, shape, walls, food, a, b, x, y, whowins, gameover }:
opacity: [0, 1],
easing: 'linear',
duration: 2000,
+ }, 3500)
+ .add({
+ targets: '#mazebox .middleLine',
+ opacity: [0, 1],
+ easing: 'linear',
+ duration: 2000,
}, 3500);
}
}, [walls, game_uuid]);
@@ -371,12 +576,13 @@ function Maze({ game_uuid, shape, walls, food, a, b, x, y, whowins, gameover }:
return (
-