This commit is contained in:
@@ -271,23 +271,22 @@ function drawSpeedLines(ctx: CanvasRenderingContext2D, centerX: number, centerY:
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
export type IcarusRunTelemetry = {
|
||||
v: 1;
|
||||
duration_ms: number;
|
||||
actions: number;
|
||||
};
|
||||
|
||||
export function IcarusGame({
|
||||
onStart,
|
||||
onFinish,
|
||||
}: {
|
||||
onStart: () => void;
|
||||
onFinish: (score: number) => void;
|
||||
onFinish: (score: number, run: IcarusRunTelemetry) => void;
|
||||
}) {
|
||||
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
const [status, setStatus] = useState<Status>("idle");
|
||||
const [score, setScore] = useState(0);
|
||||
|
||||
const onStartRef = useRef(onStart);
|
||||
useEffect(() => {
|
||||
onStartRef.current = onStart;
|
||||
}, [onStart]);
|
||||
|
||||
const onFinishRef = useRef(onFinish);
|
||||
useEffect(() => {
|
||||
onFinishRef.current = onFinish;
|
||||
@@ -306,6 +305,8 @@ export function IcarusGame({
|
||||
const boostDashAtRef = useRef<number | null>(null);
|
||||
const shatterEffectsRef = useRef<ShatterEffect[]>([]);
|
||||
const nextEntityIdRef = useRef(0);
|
||||
const runStartedAtRef = useRef<number | null>(null);
|
||||
const actionCountRef = useRef(0);
|
||||
|
||||
const resetGame = useCallback(() => {
|
||||
icarusRef.current = createInitialIcarus();
|
||||
@@ -320,19 +321,28 @@ export function IcarusGame({
|
||||
boostColumnsRemainingRef.current = 0;
|
||||
boostDashAtRef.current = null;
|
||||
shatterEffectsRef.current = [];
|
||||
runStartedAtRef.current = null;
|
||||
actionCountRef.current = 0;
|
||||
setStatus("idle");
|
||||
setScore(0);
|
||||
}, []);
|
||||
|
||||
const requestFlap = useCallback(() => {
|
||||
flapRequestedRef.current = true;
|
||||
if (statusRef.current === "dead") {
|
||||
resetGame();
|
||||
return;
|
||||
}
|
||||
|
||||
if (statusRef.current === "idle") {
|
||||
runStartedAtRef.current = Date.now();
|
||||
actionCountRef.current = 1;
|
||||
statusRef.current = "flying";
|
||||
setStatus("flying");
|
||||
onStartRef.current();
|
||||
} else if (statusRef.current === "dead") {
|
||||
resetGame();
|
||||
} else {
|
||||
actionCountRef.current += 1;
|
||||
}
|
||||
|
||||
flapRequestedRef.current = true;
|
||||
}, [resetGame]);
|
||||
|
||||
// Sur ordinateur (pas de tap tactile) : la barre d'espace fait la même
|
||||
@@ -383,6 +393,17 @@ export function IcarusGame({
|
||||
let lastFrame: number | null = null;
|
||||
let accumulator = 0;
|
||||
|
||||
function finishRun() {
|
||||
statusRef.current = "dead";
|
||||
setStatus("dead");
|
||||
const startedAt = runStartedAtRef.current;
|
||||
onFinishRef.current(scoreRef.current, {
|
||||
v: 1,
|
||||
duration_ms: startedAt === null ? 0 : Math.max(0, Date.now() - startedAt),
|
||||
actions: actionCountRef.current,
|
||||
});
|
||||
}
|
||||
|
||||
function frame(now: number) {
|
||||
if (lastFrame === null) lastFrame = now;
|
||||
const frameDt = Math.min(now - lastFrame, MAX_FRAME_DT_MS);
|
||||
@@ -505,17 +526,13 @@ export function IcarusGame({
|
||||
columnsRef.current = columnsRef.current.filter((c) => !broken.includes(c));
|
||||
setScore(scoreRef.current);
|
||||
} else {
|
||||
statusRef.current = "dead";
|
||||
setStatus("dead");
|
||||
onFinishRef.current(scoreRef.current);
|
||||
finishRun();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (boostColumnsRemainingRef.current === 0 && hasHitGround(icarusRef.current)) {
|
||||
statusRef.current = "dead";
|
||||
setStatus("dead");
|
||||
onFinishRef.current(scoreRef.current);
|
||||
finishRun();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user