From a92e1eb99a6cae72bd1a68c76d9c9459c5ee4383 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 30 Mar 2026 18:28:31 +0000 Subject: [PATCH] Fix early game-end, add double-click to start, bigger HUD sliders - endTurn now fires from draw loop once all notes are hit/missed and past gameEndTime, instead of a tight fixed timeout; fallback setTimeout extended to 5s so the music always finishes before scoring - Double-click any rhythm button to immediately start the game with current settings (delegated to rgrid to survive the onclick rebuild) - Replace tiny 50px HUD sliders with a dedicated game-controls bar below the HUD: wider sliders (140px), labelled Tempo / Volume with live % readouts; syncSliders keeps both the menu and HUD in sync https://claude.ai/code/session_01DXp3FLfbb8jFHvCJ29uWk1 --- index.html | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/index.html b/index.html index d81b584..1700d2d 100644 --- a/index.html +++ b/index.html @@ -46,6 +46,12 @@ canvas{display:block;} .stbl th{text-align:left;padding:7px 9px;border-bottom:1px solid #222;font-size:11px;opacity:.5;} .stbl td{padding:7px 9px;border-bottom:1px solid #111;font-size:12px;} .sticky-start{position:sticky;bottom:0;padding:12px 0 4px;background:linear-gradient(transparent,#0a0a0f 35%);z-index:10;display:flex;gap:8px;justify-content:center;align-items:center;width:100%;max-width:700px;} +#game-controls{display:flex;gap:0;background:#0d0d18;border-bottom:1px solid #1e1e2e;padding:5px 14px;flex-shrink:0;width:100%;align-items:center;justify-content:center;gap:28px;} +.gctrl-label{display:flex;align-items:center;gap:8px;cursor:default;} +.gctrl-icon{font-size:16px;} +.gctrl-name{font-size:11px;color:#aaa;min-width:44px;} +.gctrl-slider{width:140px;height:6px;accent-color:#805ad5;cursor:pointer;} +.gctrl-val{font-size:13px;font-weight:bold;color:#b794f4;min-width:40px;text-align:right;} #pause-overlay{display:none;position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.8);z-index:20;flex-direction:column;align-items:center;justify-content:center;gap:16px;} #pause-overlay.show{display:flex;} #pause-overlay h2{font-size:28px;color:#fff;} @@ -139,9 +145,21 @@ canvas{display:block;}
Streak0
Acc-
Player-
- - - No gamepad + No gamepad + +
+ +
@@ -2292,7 +2310,8 @@ function beginClassical(){ var n=piece.bg[i]; playSynth(ac,n.f,gameStartTime+n.t/gameSpeed,n.d/gameSpeed,n.i,n.v*1.5,gameSynthNodes); } - setTimeout(function(){if(playing)endTurn();},(piece.duration/gameSpeed)*1000+800); + gameEndTime=piece.duration/gameSpeed; + setTimeout(function(){if(playing)endTurn();},(piece.duration/gameSpeed)*1000+5000); } // ── STATE ────────────────────────────────────────────── @@ -2301,7 +2320,7 @@ let players=[{name:"Player 1"}]; let savedScores=lsLoad(); let previewAc=null,previewNodes=[],previewing=false; let gameAc=null,mp3Buffer=null,mp3Src=null; -let notes=[],gameStartTime=null,playing=false; +let notes=[],gameStartTime=null,gameEndTime=null,playing=false; let gamePlayers=[],activePIdx=0; let cScore=0,cStreak=0,cTotal=0,cGood=0,cMaxStreak=0; let laneFlash=[0,0,0,0,0],msgTmr=null,prevBtns={},gameSynthNodes=[],classicalHitMode='orchestra'; @@ -2352,6 +2371,8 @@ function syncSliders(){ ['vol-slider','hud-vol'].forEach(function(id){var e=document.getElementById(id);if(e)e.value=vv;}); var se=document.getElementById("speed-val");if(se)se.textContent=sv+"%"; var ve=document.getElementById("vol-val");if(ve)ve.textContent=vv+"%"; + var hse=document.getElementById("hud-speed-val");if(hse)hse.textContent=sv+"%"; + var hve=document.getElementById("hud-vol-val");if(hve)hve.textContent=vv+"%"; } function setSpeed(v){gameSpeed=v/100;syncSliders();saveSettings();} function setVolume(v){masterVolume=v/100;syncSliders();saveSettings();} @@ -2406,7 +2427,7 @@ function buildMenu(){ sb.onclick=function(){hiddenGenres=[];localStorage.setItem("drgameHidden","[]");buildMenu();}; gt.appendChild(sb); } - const rg=document.getElementById("rgrid");rg.innerHTML=""; + const rg=document.getElementById("rgrid");rg.innerHTML="";rg.ondblclick=()=>startGame(); var songList=SYNTH_GENRES[curGenre]||GENRES[curGenre]; var hidCount=0; songList.forEach((r,i)=>{ @@ -2530,7 +2551,7 @@ function startGame(){ updateHud(); } function stopGame(){playing=false;if(mp3Src){try{mp3Src.stop();}catch(e){}mp3Src=null;}gameSynthNodes.forEach(function(n){try{n.stop();}catch(e){}});gameSynthNodes=[];} -function resetStats(){cScore=0;cStreak=0;cTotal=0;cGood=0;cMaxStreak=0;} +function resetStats(){cScore=0;cStreak=0;cTotal=0;cGood=0;cMaxStreak=0;gameEndTime=null;} function buildNotes(r){ const bs=60/r.bpm/gameSpeed,bars=r.bars||8,res=[]; @@ -2555,7 +2576,8 @@ function beginBuiltin(){ for(const p of r.p) playDrumAt(ac,p.l,gameStartTime+bar*4*bs+p.t*bs,4,[]); const totalSec=bars*4*bs; - setTimeout(()=>{if(playing)endTurn();},totalSec*1000+800); + gameEndTime=totalSec; + setTimeout(()=>{if(playing)endTurn();},totalSec*1000+5000); } function beginMp3(){ @@ -2721,6 +2743,11 @@ function draw(){ if(laneFlash[4]){cx.beginPath();cx.arc(W/2,KICK_HIT_Y,kr,0,Math.PI*2);cx.fillStyle=LANES[4].color+"44";cx.fill();} } + // Auto-end when all notes resolved and past expected end time + if(playing&&mode==="builtin"&&gameEndTime!=null&&now>=gameEndTime){ + if(notes.length===0||notes.every(n=>n.hit||n.missed))endTurn(); + } + // Notes if(mode==="builtin"&&now>-9000){ for(const n of notes){