Highscore: bei voll geschafften Läufen (Sterne) die gebrauchte Zeit anzeigen
This commit is contained in:
parent
72aa9837ce
commit
684a430005
|
|
@ -22,8 +22,15 @@
|
||||||
1: { c: Balloon, size: 38 },
|
1: { c: Balloon, size: 38 },
|
||||||
2: { c: Cloud, size: 52 },
|
2: { c: Cloud, size: 52 },
|
||||||
3: { c: Moon, size: 40 },
|
3: { c: Moon, size: 40 },
|
||||||
4: { c: Star, size: 36 },
|
4: { c: Star, size: 34 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Gebrauchte Zeit nur bei voll geschafften Läufen (Sterne): Sekunden, ab 60s als M:SS.
|
||||||
|
function fmtTime(ms: number): string {
|
||||||
|
const s = Math.round(ms / 1000);
|
||||||
|
if (s < 60) return `${s}`;
|
||||||
|
return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="column" aria-label="Beste Flüge">
|
<div class="column" aria-label="Beste Flüge">
|
||||||
|
|
@ -46,6 +53,15 @@
|
||||||
<Symbol size={SYMBOL[slot.stage as Stage].size} />
|
<Symbol size={SYMBOL[slot.stage as Stage].size} />
|
||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
|
{#if slot.stage === 4 && slot.timeMs != null}
|
||||||
|
<span class="time" aria-label={`Zeit ${fmtTime(slot.timeMs)}`}>
|
||||||
|
<svg width="13" height="13" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="2.4" />
|
||||||
|
<path d="M12 7 L12 12 L16 14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
<span class="time-num">{fmtTime(slot.timeMs)}</span>
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<div class="placeholder"></div>
|
<div class="placeholder"></div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
@ -93,6 +109,21 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
.time {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
color: var(--c-rocket-window);
|
||||||
|
}
|
||||||
|
.time-num {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
.placeholder {
|
.placeholder {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const SCHEMA_VERSION = 1;
|
||||||
const PROGRESS_KEY = 'zahlzerlegung.progress';
|
const PROGRESS_KEY = 'zahlzerlegung.progress';
|
||||||
const SETTINGS_KEY = 'zahlzerlegung.settings';
|
const SETTINGS_KEY = 'zahlzerlegung.settings';
|
||||||
|
|
||||||
export type RunRecord = { stage: Stage; date: string };
|
export type RunRecord = { stage: Stage; date: string; timeMs?: number };
|
||||||
|
|
||||||
export type TargetProgress = {
|
export type TargetProgress = {
|
||||||
runs: number;
|
runs: number;
|
||||||
|
|
@ -87,10 +87,11 @@ export function recordRun(
|
||||||
p: Progress,
|
p: Progress,
|
||||||
target: Target,
|
target: Target,
|
||||||
stage: Stage,
|
stage: Stage,
|
||||||
date: string = new Date().toISOString()
|
date: string = new Date().toISOString(),
|
||||||
|
timeMs?: number
|
||||||
): Progress {
|
): Progress {
|
||||||
const prev = p.perTarget[target] ?? { runs: 0, top5: [] };
|
const prev = p.perTarget[target] ?? { runs: 0, top5: [] };
|
||||||
const next: RunRecord = { stage, date };
|
const next: RunRecord = { stage, date, timeMs };
|
||||||
const merged = [...prev.top5, next].sort((a, b) => {
|
const merged = [...prev.top5, next].sort((a, b) => {
|
||||||
if (b.stage !== a.stage) return b.stage - a.stage;
|
if (b.stage !== a.stage) return b.stage - a.stage;
|
||||||
return b.date.localeCompare(a.date);
|
return b.date.localeCompare(a.date);
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,9 @@ function tick() {
|
||||||
function finalize() {
|
function finalize() {
|
||||||
const g = get(game);
|
const g = get(game);
|
||||||
if (g.target === null) return;
|
if (g.target === null) return;
|
||||||
recordResult(g.target, stageFor(g.correctCount));
|
// Gebrauchte Zeit = verstrichene Zeit bis zum Ende (bei Sieg = Lösezeit für alle 10).
|
||||||
|
const elapsedMs = Math.max(0, g.totalMs - g.timeLeftMs);
|
||||||
|
recordResult(g.target, stageFor(g.correctCount), elapsedMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startGame(target: Target): void {
|
export function startGame(target: Target): void {
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ progress.subscribe((p) => {
|
||||||
if (typeof window !== 'undefined') saveProgress(p);
|
if (typeof window !== 'undefined') saveProgress(p);
|
||||||
});
|
});
|
||||||
|
|
||||||
export function recordResult(target: Target, stage: Stage): void {
|
export function recordResult(target: Target, stage: Stage, timeMs?: number): void {
|
||||||
const date = new Date().toISOString();
|
const date = new Date().toISOString();
|
||||||
progress.update((p) => recordRun(p, target, stage, date));
|
progress.update((p) => recordRun(p, target, stage, date, timeMs));
|
||||||
lastRun.set({ target, stage, date });
|
lastRun.set({ target, stage, date });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user