Skip to content

Commit 3c773ff

Browse files
committed
Portal Chess: slow teleport animation, sound, and bot pacing
1 parent 67c39fe commit 3c773ff

3 files changed

Lines changed: 26 additions & 23 deletions

File tree

src/GameContext.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,12 @@ export function GameProvider({ children }: { children: ReactNode }) {
243243
setIsBotThinking(true);
244244
(async () => {
245245
try {
246-
// Compute the bot move and ensure at least ~300ms have elapsed so the
247-
// human's own sliding animation has time to play before the board
248-
// re-renders with the bot's response.
249-
const minThinkMs = 320;
246+
// Compute the bot move and ensure enough time has elapsed so the
247+
// human's own animation has time to play before the board re-renders
248+
// with the bot's response. Teleport animations are longer (~1.6s)
249+
// so we wait extra when the previous move was a portal entry.
250+
const prevMove = state.history[state.history.length - 1];
251+
const minThinkMs = prevMove?.isPortalEntry ? 1700 : 320;
250252
const t0 = performance.now();
251253
const move = await chooseBotMove(state, lvl);
252254
const elapsed = performance.now() - t0;

src/engine/sound.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,35 +41,36 @@ export function playSound(name: SoundName, enabled = true) {
4141
else if (name === "loss") { tone(392, 140, "sawtooth", 0.14); tone(311, 220, "sawtooth", 0.14, 140); }
4242
else if (name === "draw") { tone(523, 120, "sine"); tone(523, 180, "sine", 0.12, 140); }
4343
else if (name === "teleport") {
44-
// Sci-fi whoosh: rising sine sweep + shimmering descending sine, with
45-
// a soft sawtooth tail. Total ~520ms, plays well over the visual demat.
44+
// Sci-fi whoosh stretched to match the demat (~900ms) + delay (700ms)
45+
// + remat (~900ms) visual: a rising sweep covers the demat, then a
46+
// shimmering descent times with the remat onset, plus a soft tail.
4647
const c = getCtx();
4748
if (!c) return;
4849
const now = c.currentTime;
49-
// Rising sweep: 220Hz -> 1320Hz over 220ms.
50+
// Rising sweep: 180Hz -> 1320Hz over 700ms (matches demat).
5051
const o1 = c.createOscillator();
5152
const g1 = c.createGain();
5253
o1.type = "sine";
53-
o1.frequency.setValueAtTime(220, now);
54-
o1.frequency.exponentialRampToValueAtTime(1320, now + 0.22);
54+
o1.frequency.setValueAtTime(180, now);
55+
o1.frequency.exponentialRampToValueAtTime(1320, now + 0.70);
5556
g1.gain.setValueAtTime(0, now);
56-
g1.gain.linearRampToValueAtTime(0.16, now + 0.02);
57-
g1.gain.exponentialRampToValueAtTime(0.0005, now + 0.26);
57+
g1.gain.linearRampToValueAtTime(0.16, now + 0.04);
58+
g1.gain.exponentialRampToValueAtTime(0.0005, now + 0.80);
5859
o1.connect(g1).connect(c.destination);
59-
o1.start(now); o1.stop(now + 0.30);
60-
// Shimmering descent: 1760Hz -> 660Hz starting at 200ms.
60+
o1.start(now); o1.stop(now + 0.84);
61+
// Shimmering descent: 1760Hz -> 520Hz starting at 700ms, lasting 700ms.
6162
const o2 = c.createOscillator();
6263
const g2 = c.createGain();
6364
o2.type = "triangle";
64-
o2.frequency.setValueAtTime(1760, now + 0.20);
65-
o2.frequency.exponentialRampToValueAtTime(660, now + 0.46);
66-
g2.gain.setValueAtTime(0, now + 0.20);
67-
g2.gain.linearRampToValueAtTime(0.12, now + 0.22);
68-
g2.gain.exponentialRampToValueAtTime(0.0005, now + 0.50);
65+
o2.frequency.setValueAtTime(1760, now + 0.70);
66+
o2.frequency.exponentialRampToValueAtTime(520, now + 1.40);
67+
g2.gain.setValueAtTime(0, now + 0.70);
68+
g2.gain.linearRampToValueAtTime(0.13, now + 0.74);
69+
g2.gain.exponentialRampToValueAtTime(0.0005, now + 1.50);
6970
o2.connect(g2).connect(c.destination);
70-
o2.start(now + 0.20); o2.stop(now + 0.54);
71-
// Sub-bass tail.
72-
tone(110, 180, "sawtooth", 0.07, 380);
71+
o2.start(now + 0.70); o2.stop(now + 1.54);
72+
// Sub-bass tail under the rematerialise.
73+
tone(110, 380, "sawtooth", 0.07, 1100);
7374
}
7475
} catch { /* ignore */ }
7576
}

src/styles.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,12 @@ section label { display: block; margin: 6px 0; }
282282
position: absolute;
283283
inset: 0;
284284
pointer-events: none;
285-
animation: piece-demat 520ms ease-in forwards;
285+
animation: piece-demat 900ms ease-in forwards;
286286
will-change: transform, opacity, filter;
287287
z-index: 2;
288288
}
289289
.piece-rematerialize {
290-
animation: piece-remat 520ms 360ms cubic-bezier(0.16, 1, 0.3, 1) backwards;
290+
animation: piece-remat 900ms 700ms cubic-bezier(0.16, 1, 0.3, 1) backwards;
291291
will-change: transform, opacity, filter;
292292
}
293293
@keyframes piece-demat {

0 commit comments

Comments
 (0)