feat: UI sounds, live LFO visualization, wire fix, worlds 7-12, bug fixes
- Add procedural UI sound effects (connect/disconnect, engine start/stop, level complete/fail, star earned, hint, navigation) via Tone.js - Live LFO modulation visualization: knobs animate in real-time showing modulated value, ghost dot shows base value, number glows cyan - Fix wire recalculation on zoom/pan/level re-entry (post-layout refresh) - Fix retry button to keep current patch instead of reloading level - Fix default param detection: newly added modules now populate all default params so level checkers work without manual param changes - Add worlds 7-12: Secuencias y Ritmos, Texturas de Ruido, Síntesis Sustractiva, Espacio y Stereo, Técnicas Avanzadas, Gran Final (48 new levels, 144 new possible stars, 288 total stars) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import WireLayer from '../components/WireLayer.jsx';
|
||||
import { playTarget, stopTarget, isTargetPlaying } from './targetAudio.js';
|
||||
import LevelComplete from './LevelComplete.jsx';
|
||||
import { completeLevel, saveLevelPatch, getLevelPatch, markHintUsed, wasHintUsed } from './gameState.js';
|
||||
import { playLevelComplete, playFail, playHint, playEngineStart, playEngineStop, playNav } from '../engine/uiSounds.js';
|
||||
|
||||
export default function PuzzleView({ level, levelIndex, worldLevels, onBack, onNextLevel }) {
|
||||
const [, forceUpdate] = useState(0);
|
||||
@@ -230,8 +231,10 @@ export default function PuzzleView({ level, levelIndex, worldLevels, onBack, onN
|
||||
const handleToggleAudio = async () => {
|
||||
if (state.isRunning) {
|
||||
stopAudio();
|
||||
playEngineStop();
|
||||
} else {
|
||||
await startAudio();
|
||||
playEngineStart();
|
||||
}
|
||||
emit();
|
||||
};
|
||||
@@ -252,6 +255,7 @@ export default function PuzzleView({ level, levelIndex, worldLevels, onBack, onN
|
||||
setHintUsed(true);
|
||||
setShowHint(true);
|
||||
markHintUsed(level.id);
|
||||
playHint();
|
||||
};
|
||||
|
||||
const handleCheck = () => {
|
||||
@@ -275,6 +279,9 @@ export default function PuzzleView({ level, levelIndex, worldLevels, onBack, onN
|
||||
|
||||
if (stars >= 1) {
|
||||
completeLevel(level.id, stars);
|
||||
playLevelComplete();
|
||||
} else {
|
||||
playFail();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -284,7 +291,7 @@ export default function PuzzleView({ level, levelIndex, worldLevels, onBack, onN
|
||||
<div className="gm-puzzle">
|
||||
{/* Top bar */}
|
||||
<div className="gm-puzzle-bar">
|
||||
<button className="gm-btn icon" onClick={onBack}>← Mapa</button>
|
||||
<button className="gm-btn icon" onClick={() => { playNav(); onBack(); }}>← Mapa</button>
|
||||
<div className="gm-puzzle-title">
|
||||
<span className="gm-puzzle-num">{levelIndex + 1}/{worldLevels.length}</span>
|
||||
<span className="gm-puzzle-name">{level.title}</span>
|
||||
@@ -450,7 +457,7 @@ export default function PuzzleView({ level, levelIndex, worldLevels, onBack, onN
|
||||
levelTitle={level.title}
|
||||
isLastLevel={isLastLevel}
|
||||
hintPenalty={result.hintPenalty}
|
||||
onRetry={loadLevel}
|
||||
onRetry={() => setResult(null)}
|
||||
onMap={onBack}
|
||||
onNext={onNextLevel}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user