Skip to content

Commit

Permalink
Merge pull request #139 from FleetAdmiralJakob/speed-change
Browse files Browse the repository at this point in the history
feat: add the ability to change replay speed
  • Loading branch information
delasy authored Nov 2, 2024
2 parents 17a6942 + d61ba77 commit 00c6dd2
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 16 deletions.
41 changes: 30 additions & 11 deletions app/play/[level]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Map } from "@/components/Map";
import { Page, PageTitle } from "@/components/Page";
import { Visualizer } from "@/components/Visualizer";
import { Button } from "@/components/ui/button";
import { Slider } from "@/components/ui/slider";
import {
Table,
TableBody,
Expand All @@ -19,6 +20,7 @@ import {
TableRow,
} from "@/components/ui/table";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { DEFAULT_REPLAY_SPEED } from "@/constants/visualizer";
import { api } from "@/convex/_generated/api";
import { ZombieSurvival } from "@/simulators/zombie-survival";

Expand All @@ -39,6 +41,7 @@ export default function PlayLevelPage({
const [landmineCount, setLandmineCount] = useState(0);
const flags = useQuery(api.flags.getFlags);
const [mode, setMode] = useState<"play" | "test">("play");
const [replaySpeed, setReplaySpeed] = useState(DEFAULT_REPLAY_SPEED);

// Initialize playerMap when map data is available
useEffect(() => {
Expand Down Expand Up @@ -242,6 +245,7 @@ export default function PlayLevelPage({
autoStart
onReset={handleReset}
onSimulationEnd={handleSimulationEnd}
replaySpeed={replaySpeed}
/>
{gameResult && (
<div
Expand Down Expand Up @@ -274,19 +278,34 @@ export default function PlayLevelPage({
</div>
)}
</div>
<div className="flex justify-center gap-4">
<div className="flex flex-col items-center justify-center gap-4">
{!isSimulating ? (
<>
<Button onClick={runSimulation} className="h-10">
Run Simulation
</Button>
<Button
onClick={handleClearMap}
variant="outline"
className="h-10"
>
Clear Map
</Button>
<div className="flex flex-col items-center gap-2">
<h3>Choose the speed (200ms to 2s)</h3>
<Slider
className="w-2/3"
defaultValue={[DEFAULT_REPLAY_SPEED]}
min={200}
max={2000}
step={100}
onValueChange={(value) => {
setReplaySpeed(value[0]);
}}
/>
</div>
<div className="flex justify-center gap-4">
<Button onClick={runSimulation} className="h-10">
Run Simulation
</Button>
<Button
onClick={handleClearMap}
variant="outline"
className="h-10"
>
Clear Map
</Button>
</div>
</>
) : (
<div className="flex items-center gap-x-3">
Expand Down
9 changes: 7 additions & 2 deletions components/Visualizer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as React from "react";
import { Button } from "@/components/ui/button";
import { AUTO_REPLAY_SPEED, REPLAY_SPEED } from "@/constants/visualizer";
import {
AUTO_REPLAY_SPEED,
DEFAULT_REPLAY_SPEED,
} from "@/constants/visualizer";
import { Renderer } from "@/renderer";
import { ZombieSurvival } from "@/simulators/zombie-survival";

Expand All @@ -12,6 +15,7 @@ export function Visualizer({
map,
onReset,
onSimulationEnd,
replaySpeed = DEFAULT_REPLAY_SPEED,
}: {
autoReplay?: boolean;
autoStart?: boolean;
Expand All @@ -20,6 +24,7 @@ export function Visualizer({
map: string[][];
onReset?: () => unknown;
onSimulationEnd?: (isWin: boolean) => unknown;
replaySpeed?: number;
}) {
const simulator = React.useRef<ZombieSurvival>(new ZombieSurvival(map));
const renderer = React.useRef<Renderer | null>(null);
Expand Down Expand Up @@ -79,7 +84,7 @@ export function Visualizer({
if (onSimulationEnd) {
onSimulationEnd(!simulator.current.getPlayer().dead());
}
}, REPLAY_SPEED);
}, replaySpeed);
}

React.useEffect(() => {
Expand Down
28 changes: 28 additions & 0 deletions components/ui/slider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"use client"

import * as React from "react"
import * as SliderPrimitive from "@radix-ui/react-slider"

import { cn } from "@/lib/utils"

const Slider = React.forwardRef<
React.ElementRef<typeof SliderPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
>(({ className, ...props }, ref) => (
<SliderPrimitive.Root
ref={ref}
className={cn(
"relative flex w-full touch-none select-none items-center",
className
)}
{...props}
>
<SliderPrimitive.Track className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20">
<SliderPrimitive.Range className="absolute h-full bg-primary" />
</SliderPrimitive.Track>
<SliderPrimitive.Thumb className="block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" />
</SliderPrimitive.Root>
))
Slider.displayName = SliderPrimitive.Root.displayName

export { Slider }
2 changes: 1 addition & 1 deletion constants/visualizer.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export const AUTO_REPLAY_SPEED = 1_500;
export const REPLAY_SPEED = 600;
export const DEFAULT_REPLAY_SPEED = 600;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-select": "^2.1.2",
"@radix-ui/react-slider": "^1.2.1",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.1",
"@radix-ui/react-toast": "^1.2.1",
Expand Down
4 changes: 2 additions & 2 deletions renderer/Renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { assets, loadAssets } from "./Assets";
import * as Canvas from "./Canvas";
import { type RendererEffect, RendererEffectType } from "./Effect";
import { RendererItem } from "./Item";
import { REPLAY_SPEED } from "@/constants/visualizer";
import { DEFAULT_REPLAY_SPEED } from "@/constants/visualizer";
import {
type Entity,
EntityType,
Expand Down Expand Up @@ -272,7 +272,7 @@ export class Renderer {

const positionToEffect: RendererEffect = {
type: RendererEffectType.PositionTo,
duration: REPLAY_SPEED,
duration: DEFAULT_REPLAY_SPEED,
startedAt: Date.now(),
to: {
x: to.x * this.cellSize,
Expand Down

0 comments on commit 00c6dd2

Please sign in to comment.