Regenbogenland entfernen — Sterne sind die höchste Stufe
This commit is contained in:
parent
60a0fe4297
commit
8947a28e59
|
|
@ -9,12 +9,7 @@
|
|||
--c-rocket-fin: #4a4a6e;
|
||||
--c-flame-inner: #fff4b3;
|
||||
--c-flame-outer: #ff8a3d;
|
||||
--c-rainbow-1: #ff5555;
|
||||
--c-rainbow-2: #ffa84a;
|
||||
--c-rainbow-3: #ffe34a;
|
||||
--c-rainbow-4: #6cdc6c;
|
||||
--c-rainbow-5: #4ab3ff;
|
||||
--c-rainbow-6: #b06cff;
|
||||
--c-star: #ffe34a;
|
||||
--c-correct: #5fd07a;
|
||||
--c-text: #1f1f3a;
|
||||
--c-text-on-dark: #ffffff;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
// boost — Raketenschub (Whoosh, niedrig)
|
||||
// level — neue Stufe (Akkord aufsteigend)
|
||||
// countdown — letzte 5 Sekunden (Tick pro Sekunde, höher werdend)
|
||||
// fanfare — Regenbogenland erreicht (kurze Tonfolge)
|
||||
// fanfare — Sterne erreicht / Runde gewonnen (kurze Tonfolge)
|
||||
|
||||
import { get } from 'svelte/store';
|
||||
import { settings } from '../stores/settings';
|
||||
|
|
|
|||
|
|
@ -4,15 +4,15 @@
|
|||
import Cloud from '../svg/Cloud.svelte';
|
||||
import Moon from '../svg/Moon.svelte';
|
||||
import Star from '../svg/Star.svelte';
|
||||
import Rainbow from '../svg/Rainbow.svelte';
|
||||
|
||||
import { STAGE_THRESHOLDS } from '../../game/stages';
|
||||
|
||||
type Props = { correct: number; won: boolean };
|
||||
let { correct, won }: Props = $props();
|
||||
|
||||
// Höhenpositionen 0..1 entlang der Bahn (von unten = 0 nach oben = 1)
|
||||
const STAGE_Y = [0.05, 0.25, 0.45, 0.65, 0.85, 0.97] as const;
|
||||
// Höhenpositionen 0..1 entlang der Bahn (von unten = 0 nach oben = 1); Sterne sind oben.
|
||||
const STAGE_Y = [0.05, 0.25, 0.45, 0.65, 0.85] as const;
|
||||
const WIN_Y = 0.95; // beim Sieg fliegt die Rakete hoch hinauf zu den Sternen
|
||||
|
||||
// Rakete bewegt sich kontinuierlich pro richtiger Antwort: bei den Schwellen-Counts
|
||||
// sitzt sie genau auf der jeweiligen Stufen-Markierung, dazwischen wird interpoliert.
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
}
|
||||
return STAGE_Y[4];
|
||||
}
|
||||
const rocketY = $derived(won ? STAGE_Y[5] : yFor(correct));
|
||||
const rocketY = $derived(won ? WIN_Y : yFor(correct));
|
||||
</script>
|
||||
|
||||
<div class="track" class:won>
|
||||
|
|
@ -48,9 +48,6 @@
|
|||
<Star size={20} color="#fff" />
|
||||
<Star size={24} color="#a8e8ff" />
|
||||
</div>
|
||||
<div class="marker rainbow" style="bottom: {STAGE_Y[5] * 100}%" class:visible={won}>
|
||||
<Rainbow size={140} />
|
||||
</div>
|
||||
|
||||
<div class="rocket" style="bottom: calc({rocketY * 100}% - 60px)" aria-hidden="true">
|
||||
<Rocket size={120} />
|
||||
|
|
@ -86,17 +83,6 @@
|
|||
}
|
||||
.marker.stars { display: flex; gap: 6px; left: 60%; }
|
||||
|
||||
.rainbow {
|
||||
left: 50%;
|
||||
transform: translate(-50%, 50%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.6s ease, transform 0.6s ease;
|
||||
}
|
||||
.rainbow.visible {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, 50%) scale(1.1);
|
||||
}
|
||||
|
||||
.rocket {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
import Cloud from '../svg/Cloud.svelte';
|
||||
import Moon from '../svg/Moon.svelte';
|
||||
import Star from '../svg/Star.svelte';
|
||||
import Rainbow from '../svg/Rainbow.svelte';
|
||||
|
||||
type Props = { target: Target; highlightDate?: string | null };
|
||||
let { target, highlightDate = null }: Props = $props();
|
||||
|
|
@ -24,7 +23,6 @@
|
|||
2: { c: Cloud, size: 52 },
|
||||
3: { c: Moon, size: 40 },
|
||||
4: { c: Star, size: 36 },
|
||||
5: { c: Rainbow, size: 56 },
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
|
||||
const bestStage = $derived(($progress.perTarget[target]?.top5[0]?.stage ?? 0) as number);
|
||||
const runs = $derived($progress.perTarget[target]?.runs ?? 0);
|
||||
// Fortschritt 0..1 → Höhe der Mini-Rakete in der Karte
|
||||
const progressFraction = $derived(Math.min(bestStage / 5, 1));
|
||||
const masteredAtRainbow = $derived(bestStage >= 5);
|
||||
// Fortschritt 0..1 → Höhe der Mini-Rakete in der Karte (Stufe 4 = Sterne = ganz oben)
|
||||
const progressFraction = $derived(Math.min(bestStage / 4, 1));
|
||||
const masteredAtStars = $derived(bestStage >= 4);
|
||||
</script>
|
||||
|
||||
<button class="card" type="button" onclick={() => onClick(target)} aria-label={`Zielzahl ${target}`}>
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
<div class="dot dot-5"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
{#if masteredAtRainbow}
|
||||
{#if masteredAtStars}
|
||||
<Crown size={28} />
|
||||
{/if}
|
||||
<span class="runs" aria-label={`${runs} Runden gespielt`}>
|
||||
|
|
@ -87,7 +87,7 @@
|
|||
.dot-2 { bottom: 38%; }
|
||||
.dot-3 { bottom: 58%; }
|
||||
.dot-4 { bottom: 78%; }
|
||||
.dot-5 { bottom: 92%; background: var(--c-rainbow-3); width: 6px; height: 6px; }
|
||||
.dot-5 { bottom: 92%; background: var(--c-star); width: 6px; height: 6px; }
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ describe('progress', () => {
|
|||
|
||||
it('limits top5 to five entries', () => {
|
||||
let p = emptyProgress();
|
||||
for (let i = 0; i < 10; i++) p = recordRun(p, 6, ((i % 5) + 1) as 1 | 2 | 3 | 4 | 5);
|
||||
for (let i = 0; i < 10; i++) p = recordRun(p, 6, ((i % 4) + 1) as 1 | 2 | 3 | 4);
|
||||
expect(p.perTarget[6].top5.length).toBe(5);
|
||||
expect(p.perTarget[6].runs).toBe(10);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
// Schwellen aus BRAINSTORM.md: 2/4/7/10 richtige Aufgaben pro Stufenaufstieg.
|
||||
// Während der Runde zeigt die Rakete Stufen 0..4:
|
||||
// 0 Boden, 1 Luftballon, 2 Wolken, 3 Mond, 4 Sterne.
|
||||
// Stufe 5 (Regenbogenland) ist die Win-Celebration — wird nicht durch stageFor zurückgegeben,
|
||||
// sondern durch isWin() signalisiert und im ResultScreen dargestellt.
|
||||
// Stufen 0..4: 0 Boden, 1 Luftballon, 2 Wolken, 3 Mond, 4 Sterne.
|
||||
// Die Sterne sind die höchste Stufe und zugleich der Sieg (isWin).
|
||||
|
||||
export const STAGE_THRESHOLDS = [2, 4, 7, 10] as const;
|
||||
export const TOTAL_TO_WIN = 10;
|
||||
|
||||
export type Stage = 0 | 1 | 2 | 3 | 4 | 5;
|
||||
export type Stage = 0 | 1 | 2 | 3 | 4;
|
||||
|
||||
export const STAGE_NAMES: Record<Stage, string> = {
|
||||
0: 'boden',
|
||||
|
|
@ -15,7 +13,6 @@ export const STAGE_NAMES: Record<Stage, string> = {
|
|||
2: 'wolken',
|
||||
3: 'mond',
|
||||
4: 'sterne',
|
||||
5: 'regenbogenland',
|
||||
};
|
||||
|
||||
export function stageFor(correct: number): Stage {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
import Timer from '../components/game/Timer.svelte';
|
||||
import BurstFx from '../components/game/BurstFx.svelte';
|
||||
import IconButton from '../components/shared/IconButton.svelte';
|
||||
import Star from '../components/svg/Star.svelte';
|
||||
|
||||
type Props = { target: Target };
|
||||
let { target }: Props = $props();
|
||||
|
|
@ -84,7 +85,7 @@
|
|||
/>
|
||||
{:else if $game.status === 'won'}
|
||||
<div class="end-message">
|
||||
<span class="big">🌈</span>
|
||||
<span class="big"><Star size={200} /></span>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user