mirror of
https://github.com/Xevion/Pac-Man.git
synced 2026-01-31 08:25:06 -06:00
fix(web): implement browser autoplay policy compliance with click-to-start
Add WaitingForInteraction game stage and Suspended audio state for Emscripten builds. Audio unlocks and game starts after user clicks or presses any key, satisfying browser autoplay restrictions while maintaining immediate playback on desktop.
This commit is contained in:
@@ -1,7 +1,15 @@
|
||||
import { useEffect } from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
export default function Page() {
|
||||
const [gameReady, setGameReady] = useState(false);
|
||||
const [gameStarted, setGameStarted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Set up callback for when WASM signals it's ready
|
||||
(window as any).pacmanReady = () => {
|
||||
setGameReady(true);
|
||||
};
|
||||
|
||||
if (!(window as any).Module) {
|
||||
const canvas = document.getElementById("canvas");
|
||||
|
||||
@@ -20,20 +28,54 @@ export default function Page() {
|
||||
|
||||
return () => {
|
||||
script.remove();
|
||||
delete (window as any).pacmanReady;
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleInteraction = useCallback(() => {
|
||||
if (gameReady && !gameStarted) {
|
||||
// Call the exported Rust function to start the game
|
||||
const module = (window as any).Module;
|
||||
if (module && module._start_game) {
|
||||
module._start_game();
|
||||
setGameStarted(true);
|
||||
}
|
||||
}
|
||||
}, [gameReady, gameStarted]);
|
||||
|
||||
// Handle keyboard interaction
|
||||
useEffect(() => {
|
||||
if (!gameReady || gameStarted) return;
|
||||
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
handleInteraction();
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [gameReady, gameStarted, handleInteraction]);
|
||||
|
||||
return (
|
||||
<div className="mt-4 flex justify-center h-[calc(100vh-120px)]">
|
||||
<div
|
||||
className="block border-1 border-yellow-400/50 aspect-[5/6] h-[min(calc(100vh-120px),_calc(95vw_*_6/5))] w-auto"
|
||||
className="relative block border-1 border-yellow-400/50 aspect-[5/6] h-[min(calc(100vh-120px),_calc(95vw_*_6/5))] w-auto"
|
||||
style={{
|
||||
boxShadow:
|
||||
"0 0 12px rgba(250, 204, 21, 0.35), 0 0 2px rgba(255, 255, 255, 0.25)",
|
||||
}}
|
||||
onClick={handleInteraction}
|
||||
>
|
||||
<canvas id="canvas" className="w-full h-full" />
|
||||
|
||||
{/* Click to Start overlay */}
|
||||
{gameReady && !gameStarted && (
|
||||
<div className="absolute inset-0 flex items-center justify-center bg-black/60 cursor-pointer">
|
||||
<span className="text-yellow-400 text-5xl font-bold">
|
||||
Click to Start
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user