• Updated 30 Oct, 21:11 UTC
  • Next run 31 Oct, 05:17 UTCNext 31 Oct 05:17
  • Last 7 days: 4 new models · 475 runs7 d: 4 models · 475 runs
Playable Breakout

Qwen3.8 Max (0902)Alibaba

Network offOpen alone (new tab)

Run details

Model
qwen/qwen3.8-max-0902
Route
OpenRouter API, one user message
Served by
Alibaba
Effort
xhigh, OpenRouter's default for this model
Limits
60 min · 131,072 output tokens (the model's limit)
Date
24 Oct 2026
Time
12 min 28 s
Size
34 kB
Tokens
138 in, 31,632 out (17,574 of them thinking)
List price
$0.19 at today's price ($2 in / $6 out per M)
Paid
$0.19

Raw files: output · meta.json

Exact prompt

Make a Breakout game I can play right now with the keyboard or the mouse. Give it several levels, a score and some juice.

It must be one complete, self-contained HTML file: inline all CSS and JavaScript, and make no network requests of any kind (no CDNs, web fonts or remote images). Reply with the file in a single ```html code block.

Source

34 kB 755 lines Raw

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>NOVA BREAKOUT</title>
<style>
  :root{
    --disp: 'Bahnschrift','Avenir Next Condensed','HelveticaNeue-CondensedBold','Arial Narrow',Impact,sans-serif;
    --mono: ui-monospace,'Cascadia Mono','SF Mono',Menlo,Consolas,'Liberation Mono',monospace;
    --gold:#ffd23f; --cyan:#4cc9f0; --coral:#ff4f69; --mint:#3ddc97; --ink:#eaf3ff;
  }
  *{box-sizing:border-box;margin:0;padding:0}
  html,body{height:100%}
  body{
    background:
      radial-gradient(1100px 620px at 72% -12%, rgba(76,201,240,.13), transparent 60%),
      radial-gradient(900px 540px at 10% 112%, rgba(255,79,105,.10), transparent 60%),
      radial-gradient(760px 500px at 50% 55%, rgba(20,34,72,.55), transparent 72%),
      #04060d;
    color:var(--ink); font-family:var(--mono);
    display:flex; align-items:center; justify-content:center;
    overflow:hidden; user-select:none; -webkit-user-select:none;
    animation:drift 26s ease-in-out infinite alternate;
  }
  @keyframes drift{to{background-position:0 -34px, 0 26px, 0 0, 0 0}}
  #wrap{display:flex;flex-direction:column;align-items:center;gap:10px;padding:12px}
  #stage{
    position:relative; overflow:hidden; border-radius:14px; cursor:crosshair; touch-action:none;
    border:1px solid #223458;
    box-shadow:0 0 0 6px #0a0f1c, 0 0 0 8px #1c2a45, 0 30px 80px rgba(0,0,0,.65), 0 0 60px rgba(76,201,240,.12);
  }
  #game{position:absolute;inset:0;width:100%;height:100%;display:block}
  .fx{position:absolute;inset:0;pointer-events:none;z-index:3;
    background:
      repeating-linear-gradient(0deg, rgba(255,255,255,.025) 0 1px, transparent 1px 3px),
      radial-gradient(120% 92% at 50% 42%, transparent 55%, rgba(2,5,14,.55));
  }
  /* ---------- HUD ---------- */
  #hud{position:absolute;top:0;left:0;right:0;display:flex;align-items:flex-start;
    justify-content:space-between;padding:.75em 1.1em .4em;pointer-events:none;z-index:4;
    background:linear-gradient(180deg, rgba(5,9,20,.88), rgba(5,9,20,0))}
  .hudCol{min-width:8em}
  .hudCol.mid{text-align:center}
  .hudCol.right{text-align:right}
  .lab{font-size:.6em;letter-spacing:.34em;color:#6f86ad;text-transform:uppercase}
  .big{font-family:var(--mono);font-weight:700;font-size:1.5em;line-height:1.05;
    color:#fff;text-shadow:0 0 14px rgba(76,201,240,.55)}
  .big.gold{text-shadow:0 0 14px rgba(255,210,63,.55)}
  #levelname{font-family:var(--disp);font-size:1.02em;letter-spacing:.18em;color:var(--gold);
    text-shadow:0 0 12px rgba(255,210,63,.4);margin-top:.15em}
  #levelsub{font-size:.62em;letter-spacing:.3em;color:#7d92b8}
  #lives{margin-top:.35em;display:flex;gap:.3em;justify-content:flex-end}
  #lives i{display:block;width:1.35em;height:.42em;border-radius:.25em;
    background:linear-gradient(180deg,#8ff0ff,#2ea8d8);box-shadow:0 0 8px rgba(76,201,240,.7)}
  #muteBtn{pointer-events:auto;margin-top:.5em;background:rgba(14,22,40,.85);color:#9fb4d8;
    border:1px solid #2b3f66;border-radius:.45em;font-family:var(--mono);font-size:.68em;
    letter-spacing:.15em;padding:.3em .6em;cursor:pointer;transition:.15s}
  #muteBtn:hover{color:#fff;border-color:var(--cyan);box-shadow:0 0 10px rgba(76,201,240,.4)}
  /* ---------- Overlays ---------- */
  .ov{position:absolute;inset:0;z-index:6;display:flex;align-items:center;justify-content:center;
    text-align:center;background:rgba(4,8,18,.62);
    transition:opacity .35s ease, visibility .35s}
  .ov.hidden{opacity:0;visibility:hidden;pointer-events:none}
  .ovBox{animation:pop .5s cubic-bezier(.2,1.4,.3,1)}
  @keyframes pop{from{transform:scale(.9) translateY(16px);opacity:0}}
  .sysTag{font-size:.62em;letter-spacing:.5em;color:#5d7ba8;margin-bottom:1em}
  .logo{font-family:var(--disp);font-weight:900;line-height:.92;letter-spacing:.02em}
  .logo .l1{display:block;font-size:4.6em;color:#eafaff;
    text-shadow:-3px 0 var(--coral),3px 0 var(--cyan),0 0 30px rgba(76,201,240,.5);
    animation:floaty 3.4s ease-in-out infinite}
  .logo .l2{display:block;font-size:2.7em;color:var(--gold);letter-spacing:.3em;margin-top:.12em;
    text-shadow:0 4px 0 #6b4a00,0 0 26px rgba(255,210,63,.45)}
  @keyframes floaty{50%{transform:translateY(-5px)}}
  .tag{margin:1.1em 0 1.4em;font-size:.66em;letter-spacing:.28em;color:#8fa7cc}
  .ctrls{display:flex;gap:1.4em;justify-content:center;flex-wrap:wrap;margin-bottom:1.6em}
  .ctrls div{border:1px solid #24365c;background:rgba(10,17,34,.7);padding:.5em .8em;border-radius:.4em}
  .ctrls b{display:block;font-size:.6em;letter-spacing:.25em;color:#6f86ad;margin-bottom:.3em}
  .ctrls i{font-style:normal;font-size:.75em;color:#dce9ff}
  .prompt{font-family:var(--disp);font-size:1.1em;letter-spacing:.3em;color:#fff;
    text-shadow:0 0 16px rgba(255,210,63,.6)}
  .blink{animation:blink 1.1s steps(2,jump-none) infinite}
  @keyframes blink{50%{opacity:.15}}
  .hiLine{margin-top:1.4em;font-size:.7em;letter-spacing:.3em;color:#7d92b8}
  .hiLine span{color:var(--gold)}
  .bigTitle{font-family:var(--disp);font-weight:900;font-size:3.4em;letter-spacing:.06em}
  .bigTitle.red{color:var(--coral);text-shadow:-3px 0 rgba(76,201,240,.8),0 0 30px rgba(255,79,105,.6)}
  .bigTitle.grn{color:var(--mint);text-shadow:0 0 30px rgba(61,220,151,.6)}
  .ovScore{margin:.7em 0 .2em;font-size:.7em;letter-spacing:.3em;color:#8fa7cc}
  .ovScore b{display:block;font-size:2.6em;color:#fff;letter-spacing:.05em;
    text-shadow:0 0 18px rgba(76,201,240,.6)}
  .newBest{display:none;font-size:.72em;letter-spacing:.35em;color:var(--gold);
    text-shadow:0 0 14px rgba(255,210,63,.7);margin-top:.6em}
  .newBest.on{display:block;animation:blink 1s steps(2,jump-none) infinite}
  /* ---------- footer ---------- */
  #foot{font-size:11px;letter-spacing:.22em;color:#4d6285;text-transform:uppercase}
  #foot b{color:#7f9ac4;font-weight:400}
</style>
</head>
<body>
<div id="wrap">
  <div id="stage">
    <canvas id="game"></canvas>
    <div class="fx"></div>

    <div id="hud">
      <div class="hudCol left">
        <div class="lab">Score</div>
        <div class="big gold" id="score">0</div>
        <div id="lives"></div>
      </div>
      <div class="hudCol mid">
        <div id="levelname">SECTOR 1</div>
        <div id="levelsub">OPENING SALVO</div>
      </div>
      <div class="hudCol right">
        <div class="lab">Best</div>
        <div class="big" id="hiscore">0</div>
        <button id="muteBtn" title="toggle sound">♪ ON</button>
      </div>
    </div>

    <div class="ov" id="ovTitle">
      <div class="ovBox">
        <div class="sysTag">MK·II ARCADE SYSTEM</div>
        <h1 class="logo"><span class="l1">NOVA</span><span class="l2">BREAKOUT</span></h1>
        <p class="tag">SMASH THE WALL · CHASE THE COMBO · SURVIVE 7 SECTORS</p>
        <div class="ctrls">
          <div><b>MOVE</b><i>MOUSE / ← →</i></div>
          <div><b>LAUNCH · FIRE</b><i>SPACE / CLICK</i></div>
          <div><b>PAUSE</b><i>P</i></div>
          <div><b>SOUND</b><i>M</i></div>
        </div>
        <div class="prompt blink">PRESS ENTER OR CLICK TO START</div>
        <div class="hiLine">BEST RUN — <span id="hiTitle">0</span></div>
      </div>
    </div>

    <div class="ov hidden" id="ovPause">
      <div class="ovBox">
        <div class="bigTitle" style="color:#dce9ff;text-shadow:0 0 24px rgba(76,201,240,.5)">PAUSED</div>
        <p class="tag">PRESS P TO RESUME</p>
      </div>
    </div>

    <div class="ov hidden" id="ovOver">
      <div class="ovBox">
        <div class="bigTitle red">GAME OVER</div>
        <div class="ovScore">FINAL SCORE<b id="overScore">0</b></div>
        <div class="newBest" id="overNew">★ NEW BEST ★</div>
        <p class="prompt blink" style="margin-top:1.4em">ENTER — TRY AGAIN</p>
      </div>
    </div>

    <div class="ov hidden" id="ovWin">
      <div class="ovBox">
        <div class="bigTitle grn">SYSTEM CLEARED</div>
        <p class="tag">ALL 7 SECTORS DEMOLISHED</p>
        <div class="ovScore">FINAL SCORE<b id="winScore">0</b></div>
        <div class="newBest" id="winNew">★ NEW BEST ★</div>
        <p class="prompt blink" style="margin-top:1.2em">ENTER — PLAY AGAIN</p>
      </div>
    </div>
  </div>
  <div id="foot"><b>MOUSE / ←→</b> move · <b>SPACE</b> launch &amp; fire · <b>P</b> pause · <b>M</b> sound</div>
</div>

<script>
'use strict';
/* ============================ helpers ============================ */
const $=s=>document.querySelector(s);
const clamp=(v,a,b)=>v<a?a:v>b?b:v;
const rand=(a,b)=>a+Math.random()*(b-a);
const TAU=Math.PI*2;
function shade(hex,p){ // p>0 lighten, p<0 darken
  const n=parseInt(hex.slice(1),16); let r=n>>16&255,g=n>>8&255,b=n&255;
  if(p>=0){r+=(255-r)*p;g+=(255-g)*p;b+=(255-b)*p;}else{r*=1+p;g*=1+p;b*=1+p;}
  return `rgb(${r|0},${g|0},${b|0})`;
}
function rr(c,x,y,w,h,r){r=Math.min(r,w/2,h/2);c.beginPath();c.moveTo(x+r,y);
  c.arcTo(x+w,y,x+w,y+h,r);c.arcTo(x+w,y+h,x,y+h,r);c.arcTo(x,y+h,x,y,r);c.arcTo(x,y,x+w,y,r);c.closePath();}

/* ============================ audio ============================ */
let AC=null,master=null,noiseBuf=null,muted=false;
function ensureAudio(){
  if(!AC){try{
    AC=new (window.AudioContext||window.webkitAudioContext)();
    master=AC.createGain();master.gain.value=.4;master.connect(AC.destination);
    noiseBuf=AC.createBuffer(1,AC.sampleRate,AC.sampleRate);
    const d=noiseBuf.getChannelData(0);for(let i=0;i<d.length;i++)d[i]=Math.random()*2-1;
  }catch(e){}}
  if(AC&&AC.state==='suspended')AC.resume();
}
function tone(f0,f1,dur,type,vol,delay=0){
  if(!AC||muted)return;const t=AC.currentTime+delay;
  const o=AC.createOscillator(),g=AC.createGain();
  o.type=type;o.frequency.setValueAtTime(Math.max(f0,1),t);
  o.frequency.exponentialRampToValueAtTime(Math.max(f1,1),t+dur);
  g.gain.setValueAtTime(vol,t);g.gain.exponentialRampToValueAtTime(.0001,t+dur);
  o.connect(g);g.connect(master);o.start(t);o.stop(t+dur+.03);
}
function nz(dur,vol,f,delay=0){
  if(!AC||muted)return;const t=AC.currentTime+delay;
  const s=AC.createBufferSource();s.buffer=noiseBuf;s.loop=true;
  const f1=AC.createBiquadFilter();f1.type='bandpass';f1.frequency.value=f;f1.Q.value=.9;
  const g=AC.createGain();g.gain.setValueAtTime(vol,t);g.gain.exponentialRampToValueAtTime(.0001,t+dur);
  s.connect(f1);f1.connect(g);g.connect(master);s.start(t);s.stop(t+dur+.03);
}
const sfx={
  paddle:rel=>{tone(210+130*(1-Math.abs(rel)),400,.06,'square',.2);nz(.04,.08,900);},
  brick:cb=>{const b=240*Math.pow(1.059,Math.min(cb,16));tone(b,b*1.5,.09,'square',.2);nz(.12,.18,1900);},
  tick:()=>tone(660,520,.05,'triangle',.15),
  steel:()=>{tone(1250,900,.05,'triangle',.14);nz(.05,.1,4200);},
  launch:()=>tone(180,540,.12,'square',.2),
  laser:()=>tone(950,220,.09,'square',.16),
  spawn:()=>tone(500,560,.07,'sine',.1),
  power:()=>{tone(660,660,.07,'triangle',.22);tone(990,990,.1,'triangle',.22,.07);},
  life:()=>{tone(520,520,.08,'triangle',.22);tone(780,780,.08,'triangle',.22,.08);tone(1040,1040,.14,'triangle',.22,.16);},
  hurt:()=>{tone(300,60,.5,'sawtooth',.26);nz(.3,.22,300);},
  clear:()=>[523,659,784,1046,1318].forEach((f,i)=>tone(f,f,.12,'triangle',.22,i*.09)),
  over:()=>tone(220,38,1.1,'sawtooth',.26),
  win:()=>{[523,659,784,1046,1318,1568].forEach((f,i)=>tone(f,f,.16,'triangle',.24,i*.11));nz(.6,.12,2400,.3);}
};

/* ============================ constants ============================ */
const W=900,H=640,COLS=12,BW=64,BH=22,GAPX=6,GAPY=6,
      OX=(W-(COLS*BW+(COLS-1)*GAPX))/2,OY=84,PY=H-46,PH=16;
const PAL=['#ffcf3f','#ff8a3d','#ff4f69','#b465da','#4cc9f0','#3ddc97'];
const C2='#9fd8ff',C3='#ffb703',CST='#7c8ba1';
const BASE={1:50,2:120,3:250};
const LEVELS=[
 {name:'OPENING SALVO',speed:330,map:[
  '111111111111','111111111111','111111111111','111111111111']},
 {name:'CHECKMATE',speed:350,map:[
  '1.1.1.1.1.1.','.1.1.1.1.1.1','2.2.2.2.2.2.','.1.1.1.1.1.1','1.1.1.1.1.1.']},
 {name:'THE PYRAMID',speed:368,map:[
  '.....11.....','....1111....','...112211...','..11222211..','.1122332211.','112233332211']},
 {name:'THE VAULT',speed:384,map:[
  '.SSSSSSSSSS.','S1111111111S','S1222222221S','S1111111111S','.SSSSSSSSSS.']},
 {name:'THE INVADER',speed:400,map:[
  '...2.....2..','....2...2...','...2222222..','..22.222.22.','.22223332222',
  '.2.2222222.2','.2.2.....2.2','...22...22..']},
 {name:'SKYLINE',speed:414,map:[
  '...3...3....','.2.3.2.3..2.','.2.222.3.22.','121222122221','11.11.11.11.']},
 {name:'FINAL FORTRESS',speed:430,map:[
  '2S22333322S2','S3232332323S','3232S22S2323','S3232332323S','2S22333322S2']}
];

/* ============================ dom refs ============================ */
const stage=$('#stage'),cv=$('#game'),ctx=cv.getContext('2d');
const scoreEl=$('#score'),hiEl=$('#hiscore'),lvNameEl=$('#levelname'),lvSubEl=$('#levelsub'),
      livesEl=$('#lives'),muteBtn=$('#muteBtn'),hiTitle=$('#hiTitle'),
      ovTitle=$('#ovTitle'),ovPause=$('#ovPause'),ovOver=$('#ovOver'),ovWin=$('#ovWin'),
      overScore=$('#overScore'),overNew=$('#overNew'),winScore=$('#winScore'),winNew=$('#winNew');
const showOv=o=>o.classList.remove('hidden'),hideOv=o=>o.classList.add('hidden');

/* ============================ state ============================ */
let state='title',score=0,hi=0,lives=3,level=0,levelSpeed=330,remaining=0;
let combo=0,comboPulse=0,timeScale=1,shake=0,flashA=0,flashC='#fff';
let bannerT=0,bannerMain='',bannerSub='',levelBonus=0,clearT=0,fwT=0,loseCd=0,fireCd=0;
let bricks=[],balls=[],caps=[],bolts=[],parts=[],pops=[];
const paddle={x:W/2-56,w:112,wt:112,flash:0,squash:0};
const effects={wide:0,laser:0,slow:0};
const keys={l:0,r:0};let mouseOn=false,mouseX=W/2;
try{hi=parseInt(localStorage.getItem('novaBreakoutHi'))||0;}catch(e){}

/* stars + nebulae */
const stars=[];for(let i=0;i<110;i++)stars.push({x:Math.random()*W,y:Math.random()*H,
  z:.25+Math.random()*.75,ph:Math.random()*TAU,sp:rand(.6,2.2)});
const nebs=[{x:W*.25,y:H*.3,r:320,c:'rgba(76,201,240,.10)',ph:0},
            {x:W*.75,y:H*.62,r:360,c:'rgba(255,79,105,.08)',ph:2},
            {x:W*.55,y:H*.15,r:260,c:'rgba(255,210,63,.05)',ph:4}];

/* ============================ setup ============================ */
function buildBricks(i){
  bricks=[];remaining=0;
  const m=LEVELS[i].map;
  for(let r=0;r<m.length;r++)for(let c=0;c<COLS;c++){
    const ch=m[r][c];if(ch==='.')continue;
    const x=OX+c*(BW+GAPX),y=OY+r*(BH+GAPY);
    const b={x,y,w:BW,h:BH,cx:x+BW/2,cy:y+BH/2,alive:true,flash:0,type:'brick',hp:1,maxHp:1,row:r,color:PAL[r%PAL.length]};
    if(ch==='S'){b.type='steel';b.color=CST;}else{b.hp=b.maxHp=ch|0;b.color=b.maxHp===1?PAL[r%PAL.length]:b.maxHp===2?C2:C3;remaining++;}
    bricks.push(b);
  }
}
function makeStuckBall(){balls=[{x:paddle.x+paddle.w/2,y:PY-8,vx:0,vy:0,r:7,speed:levelSpeed,trail:[],stuck:true}];}
function loadLevel(i){
  level=i;buildBricks(i);levelSpeed=LEVELS[i].speed;
  caps=[];bolts=[];paddle.x=W/2-paddle.w/2;paddle.wt=112;paddle.w=112;
  effects.wide=effects.laser=effects.slow=0;combo=0;
  makeStuckBall();
  bannerMain='SECTOR '+(i+1);bannerSub=LEVELS[i].name;bannerT=2.3;
  lvNameEl.textContent='SECTOR '+(i+1);lvSubEl.textContent=LEVELS[i].name;
}
function updateHUD(){
  scoreEl.textContent=score.toLocaleString('en-US');
  hiEl.textContent=hi.toLocaleString('en-US');
  livesEl.innerHTML='<i></i>'.repeat(Math.max(0,lives));
}
function reset(){
  score=0;lives=3;combo=0;parts=[];pops=[];loseCd=0;
  loadLevel(0);updateHUD();
}

/* ============================ juice ============================ */
function addScore(n,x,y,big){
  score+=n;if(score>hi){hi=score;try{localStorage.setItem('novaBreakoutHi',hi);}catch(e){}}
  if(x!==undefined)pops.push({x,y,t:big?'+ '+n.toLocaleString('en-US'):'+'+n,life:big?1.4:.9,
    max:big?1.4:.9,big:!!big,col:big?'#3ddc97':'#ffd23f'});
  updateHUD();
}
function burst(x,y,col,n,pw){
  for(let i=0;i<n;i++){const a=rand(0,TAU),s=rand(60,240)*(pw||1);
    parts.push({x,y,vx:Math.cos(a)*s,vy:Math.sin(a)*s-60,g:520,life:rand(.35,.8),max:.8,
      size:rand(2,5),col,type:'shard',rot:rand(0,TAU),vr:rand(-8,8)});
    if(parts.length>430)parts.shift();}
}
function sparks(x,y,n){
  for(let i=0;i<n;i++){const a=rand(0,TAU),s=rand(120,340);
    parts.push({x,y,vx:Math.cos(a)*s,vy:Math.sin(a)*s,g:200,life:rand(.15,.35),max:.35,
      size:rand(1,2.4),col:'#dfe9ff',type:'spark'});
    if(parts.length>430)parts.shift();}
}
function firework(x,y){
  const col=PAL[(Math.random()*PAL.length)|0];
  for(let i=0;i<26;i++){const a=i/26*TAU,s=rand(90,260);
    parts.push({x,y,vx:Math.cos(a)*s,vy:Math.sin(a)*s,g:160,life:rand(.5,1),max:1,
      size:rand(1.6,3),col,type:'spark'});}
}

/* ============================ gameplay ============================ */
function spawnCap(x,y){
  if(caps.length>=3||Math.random()>.14)return;
  const r=Math.random(),type=r<.26?'W':r<.52?'L':r<.72?'T':r<.92?'S':'H';
  caps.push({x,y,vy:135,type,wob:rand(0,TAU)});sfx.spawn();
}
function applyCap(cp){
  if(cp.type==='H'){
    if(lives<6){lives++;pops.push({x:cp.x,y:PY-24,t:'+1 SHIP',life:1.2,max:1.2,big:true,col:'#3ddc97'});}
    else addScore(500,cp.x,PY-24,true);
    sfx.life();
  }else if(cp.type==='W'){effects.wide=12;paddle.wt=178;sfx.power();}
  else if(cp.type==='L'){effects.laser=10;sfx.power();}
  else if(cp.type==='S'){effects.slow=8;sfx.power();}
  else if(cp.type==='T'){
    const snap=balls.filter(b=>!b.stuck);
    for(const b of snap){if(balls.length>=9)break;
      const sp=b.speed,a=Math.atan2(b.vy,b.vx);
      for(const da of[-.42,.42]){if(balls.length>=9)break;
        balls.push({x:b.x,y:b.y,vx:Math.cos(a+da)*sp,vy:Math.sin(a+da)*sp,r:7,speed:sp,trail:[],stuck:false});}}
    sfx.power();
  }
  updateHUD();
}
function damageBrick(b,dmg,px,py,opt){
  opt=opt||{};
  if(b.type==='steel'){b.flash=1;sparks(px,py,6);if(!opt.silent){sfx.steel();shake+=1.2;}return;}
  b.hp-=dmg;b.flash=1;
  if(b.hp<=0){
    b.alive=false;remaining--;
    burst(b.cx,b.cy,b.color,14+dmg*4,1);shake+=1.5+b.maxHp*.8;
    if(opt.silent)return;
    if(!opt.noCombo){combo++;comboPulse=1;}
    const multi=Math.min(6,1+Math.floor(combo/4));
    addScore(BASE[b.maxHp]*multi,b.cx,b.cy);
    spawnCap(b.cx,b.cy);
    opt.noCombo?sfx.tick():sfx.brick(combo);
    if(remaining<=0)startClear();
  }else{
    sparks(px,py,5);
    if(!opt.silent){addScore(20);sfx.tick();shake+=.6;}
  }
}
function startClear(){
  if(state!=='play')return;
  state='clear';clearT=0;fwT=0;
  levelBonus=300+level*200+lives*150;
  addScore(levelBonus);sfx.clear();shake+=3;
}
function loseLife(){
  lives--;updateHUD();combo=0;
  shake=14;flashA=.55;flashC='rgba(255,60,70,';
  stage.classList.add('hurt');setTimeout(()=>stage.classList.remove('hurt'),350);
  sfx.hurt();
  if(lives<=0){
    state='over';overScore.textContent=score.toLocaleString('en-US');
    overNew.classList.toggle('on',score>=hi&&score>0);showOv(ovOver);sfx.over();
  }else{loseCd=.7;makeStuckBall();}
}
function launch(){
  const b=balls[0];if(!b||!b.stuck)return;
  b.stuck=false;const a=-Math.PI/2+rand(-.3,.3);
  b.vx=Math.cos(a)*levelSpeed;b.vy=Math.sin(a)*levelSpeed;b.speed=levelSpeed;
  state='play';sfx.launch();
}
function fireLaser(){
  if(effects.laser<=0||fireCd>0)return;
  fireCd=.16;sfx.laser();
  bolts.push({x:paddle.x+8,y:PY-4},{x:paddle.x+paddle.w-8,y:PY-4});
  sparks(paddle.x+8,PY-2,3);sparks(paddle.x+paddle.w-8,PY-2,3);
}

/* ============================ physics ============================ */
function movePaddle(dt){
  if(keys.l||keys.r){
    const d=((keys.r?1:0)-(keys.l?1:0))*640*dt;
    paddle.x=clamp(paddle.x+d,-10,W-paddle.w+10);
  }else if(mouseOn){
    paddle.x=clamp(mouseX-paddle.w/2,-10,W-paddle.w+10);
  }
  paddle.w+=(paddle.wt-paddle.w)*Math.min(1,8*dt);
  paddle.flash=Math.max(0,paddle.flash-dt*5);
  paddle.squash=Math.max(0,paddle.squash-dt*4);
}
function paddleHit(b){
  const rel=clamp((b.x-(paddle.x+paddle.w/2))/(paddle.w/2),-1,1);
  b.speed=Math.min(b.speed*1.028+4,680);
  const a=-Math.PI/2+rel*1.05;
  b.vx=Math.cos(a)*b.speed;b.vy=Math.sin(a)*b.speed;
  b.y=PY-b.r-.5;
  combo=0;paddle.flash=1;paddle.squash=1;
  sparks(b.x,PY,5);sfx.paddle(rel);
}
function stepWorld(dt,silent){
  /* capsules */
  for(let i=caps.length-1;i>=0;i--){const c=caps[i];
    c.y+=c.vy*dt;c.wob+=dt*5;c.x+=Math.sin(c.wob)*12*dt;
    if(!silent&&c.y+9>=PY&&c.y-9<=PY+PH&&c.x>=paddle.x-17&&c.x<=paddle.x+paddle.w+17){
      applyCap(c);burst(c.x,PY,'#ffffff',8,.6);caps.splice(i,1);continue;}
    if(c.y>H+30)caps.splice(i,1);
  }
  /* laser bolts */
  for(let i=bolts.length-1;i>=0;i--){const L=bolts[i];L.y-=900*dt;
    let hit=null;
    for(const b of bricks){if(!b.alive)continue;
      if(L.x>b.x-2&&L.x<b.x+b.w+2&&L.y>b.y-2&&L.y<b.y+b.h+2){hit=b;break;}}
    if(hit){damageBrick(hit,1,L.x,L.y,{silent,noCombo:true});bolts.splice(i,1);continue;}
    if(L.y<-20)bolts.splice(i,1);
  }
  /* balls */
  for(let i=balls.length-1;i>=0;i--){const b=balls[i];
    if(b.stuck){b.x=paddle.x+paddle.w/2;b.y=PY-b.r-2;continue;}
    const n=3,sdt=dt/n;
    for(let s=0;s<n;s++){
      b.x+=b.vx*sdt;b.y+=b.vy*sdt;
      if(b.x<b.r){b.x=b.r;b.vx=Math.abs(b.vx);}
      if(b.x>W-b.r){b.x=W-b.r;b.vx=-Math.abs(b.vx);}
      if(b.y<b.r){b.y=b.r;b.vy=Math.abs(b.vy);}
      if(b.vy>0&&b.y+b.r>=PY&&b.y+b.r<=PY+PH+16&&b.x>=paddle.x-b.r&&b.x<=paddle.x+paddle.w+b.r)paddleHit(b);
      for(const k of bricks){if(!k.alive)continue;
        const dx=Math.abs(b.x-k.cx),dy=Math.abs(b.y-k.cy);
        if(dx>k.w/2+b.r||dy>k.h/2+b.r)continue;
        const ox=k.w/2+b.r-dx,oy=k.h/2+b.r-dy;
        if(ox<oy){b.vx=(b.x>k.cx?1:-1)*Math.abs(b.vx);b.x+=b.x>k.cx?ox:-ox;}
        else{b.vy=(b.y>k.cy?1:-1)*Math.abs(b.vy);b.y+=b.y>k.cy?oy:-oy;}
        if(Math.abs(b.vy)<b.speed*.22)b.vy=(b.vy>=0?1:-1)*b.speed*.22;
        const m=Math.hypot(b.vx,b.vy)||1;b.vx*=b.speed/m;b.vy*=b.speed/m;
        damageBrick(k,1,b.x,b.y,{silent});break;
      }
    }
    b.trail.push({x:b.x,y:b.y});if(b.trail.length>10)b.trail.shift();
    if(b.y>H+40)balls.splice(i,1);
  }
}

/* ============================ update ============================ */
function spawnAttractBall(){
  const a=rand(.5,1.2)*(Math.random()<.5?1:-1);
  balls=[{x:rand(120,W-120),y:130,vx:Math.cos(Math.PI/2+a)*320,vy:Math.abs(Math.sin(Math.PI/2+a))*320,
    r:7,speed:320,trail:[],stuck:false}];
}
function ambient(dt){
  shake=Math.max(0,shake-dt*26);
  flashA=Math.max(0,flashA-dt*1.6);
  comboPulse=Math.max(0,comboPulse-dt*3);
  for(const s of stars){s.x-=s.z*7*dt;s.y+=s.z*13*dt;
    if(s.y>H+2){s.y=-2;s.x=Math.random()*W}if(s.x<-2){s.x=W+2;s.y=Math.random()*H}}
}
function updateFX(dt){
  for(let i=parts.length-1;i>=0;i--){const p=parts[i];p.life-=dt;
    if(p.life<=0){parts.splice(i,1);continue;}
    p.vy+=p.g*dt;p.x+=p.vx*dt;p.y+=p.vy*dt;if(p.rot!==undefined)p.rot+=p.vr*dt;}
  for(let i=pops.length-1;i>=0;i--){const p=pops[i];p.life-=dt;p.y-=36*dt;
    if(p.life<=0)pops.splice(i,1);}
}
function update(dt,t){
  ambient(dt);
  const target=effects.slow>0?.55:1;
  timeScale+=(target-timeScale)*Math.min(1,6*dt);
  if(state==='title'){
    movePaddle(dt);
    const b=balls[0];
    if(b&&!b.stuck)paddle.x+=((b.x-paddle.w/2)-paddle.x)*Math.min(1,4.5*dt);
    stepWorld(dt,true);
    if(!balls.length)spawnAttractBall();
    if(remaining<10)buildBricks(0);
    updateFX(dt);return;
  }
  if(state==='paused'){updateFX(dt);return;}
  if(state==='serve'){
    movePaddle(dt);stepWorld(dt,false);updateFX(dt);
    if(loseCd>0)loseCd-=dt;return;
  }
  if(state==='play'){
    fireCd-=dt;
    effects.wide=Math.max(0,effects.wide-dt);
    effects.laser=Math.max(0,effects.laser-dt);
    effects.slow=Math.max(0,effects.slow-dt);
    if(effects.wide<=0)paddle.wt=112;
    movePaddle(dt);
    const wdt=dt*timeScale;
    stepWorld(wdt,false);
    updateFX(dt);
    if(!balls.length&&loseCd<=0)loseLife();
    return;
  }
  if(state==='clear'){
    movePaddle(dt);clearT+=dt;fwT-=dt;
    if(fwT<=0){fwT=.28;firework(rand(100,W-100),rand(90,300));}
    updateFX(dt);
    if(clearT>2.6){
      if(level+1>=LEVELS.length){
        state='win';winScore.textContent=score.toLocaleString('en-US');
        winNew.classList.toggle('on',score>=hi&&score>0);showOv(ovWin);sfx.win();
      }else{loadLevel(level+1);state='serve';}
    }
    return;
  }
  updateFX(dt); /* over / win */
}

/* ============================ render ============================ */
function drawBrick(b){
  const c=ctx;
  c.fillStyle=b.color;rr(c,b.x,b.y,b.w,b.h,4);c.fill();
  c.fillStyle='rgba(255,255,255,.28)';c.fillRect(b.x+3,b.y+2,b.w-6,2.5);
  c.fillStyle='rgba(0,0,20,.3)';c.fillRect(b.x+3,b.y+b.h-4,b.w-6,2);
  if(b.type==='steel'){
    c.save();rr(c,b.x,b.y,b.w,b.h,4);c.clip();
    c.strokeStyle='rgba(255,255,255,.12)';c.lineWidth=3;
    for(let x=b.x-b.h;x<b.x+b.w;x+=10){c.beginPath();c.moveTo(x,b.y+b.h+2);c.lineTo(x+b.h+4,b.y-2);c.stroke();}
    c.restore();
    c.fillStyle='#39424f';
    for(const p of[[5,5],[b.w-5,5],[5,b.h-5],[b.w-5,b.h-5]]){c.beginPath();c.arc(b.x+p[0],b.y+p[1],1.8,0,TAU);c.fill();}
  }else{
    c.strokeStyle='rgba(8,12,26,.4)';c.lineWidth=1;rr(c,b.x+.5,b.y+.5,b.w-1,b.h-1,4);c.stroke();
    if(b.hp<b.maxHp){
      c.strokeStyle='rgba(10,14,28,.6)';c.lineWidth=1.4;c.beginPath();
      c.moveTo(b.x+b.w*.3,b.y+2);c.lineTo(b.x+b.w*.42,b.y+b.h*.5);c.lineTo(b.x+b.w*.28,b.y+b.h-2);
      c.moveTo(b.x+b.w*.68,b.y+2);c.lineTo(b.x+b.w*.6,b.y+b.h*.55);c.lineTo(b.x+b.w*.76,b.y+b.h-2);
      c.stroke();
    }
    if(b.maxHp>1){c.fillStyle='rgba(8,12,26,.55)';
      for(let i=0;i<b.maxHp;i++){c.beginPath();c.arc(b.cx-(b.maxHp-1)*4+i*8,b.y+b.h-5,1.7,0,TAU);c.fill();}}
  }
  if(b.flash>0){c.fillStyle=`rgba(255,255,255,${b.flash*.75})`;rr(c,b.x,b.y,b.w,b.h,4);c.fill();b.flash=Math.max(0,b.flash-.08);}
}
function pill(x,y,label,col,frac){
  ctx.font='700 10px '+'ui-monospace,Menlo,Consolas,monospace';
  const w=Math.max(64,ctx.measureText(label).width+26);
  ctx.fillStyle='rgba(9,14,28,.85)';rr(ctx,x,y,w,18,9);ctx.fill();
  ctx.strokeStyle=col;ctx.lineWidth=1.2;rr(ctx,x,y,w,18,9);ctx.stroke();
  if(frac!==undefined){ctx.fillStyle=col;ctx.globalAlpha=.4;rr(ctx,x+2,y+13,(w-4)*frac,3,1.5);ctx.fill();ctx.globalAlpha=1;}
  ctx.fillStyle='#eaf3ff';ctx.textAlign='center';ctx.textBaseline='middle';
  ctx.fillText(label,x+w/2,y+9);
  return w;
}
const DFONT="'Bahnschrift','Avenir Next Condensed','Arial Narrow',Impact,sans-serif";
function render(t){
  const s=cv._sc||1;
  ctx.setTransform(s,0,0,s,0,0);
  /* backdrop */
  const g=ctx.createLinearGradient(0,0,0,H);
  g.addColorStop(0,'#0a1226');g.addColorStop(.55,'#070c1a');g.addColorStop(1,'#05080f');
  ctx.fillStyle=g;ctx.fillRect(0,0,W,H);
  for(const n of nebs){
    const nx=n.x+Math.sin(t*.13+n.ph)*40,ny=n.y+Math.cos(t*.1+n.ph)*26;
    const rg=ctx.createRadialGradient(nx,ny,0,nx,ny,n.r);
    rg.addColorStop(0,n.c);rg.addColorStop(1,'rgba(0,0,0,0)');
    ctx.fillStyle=rg;ctx.fillRect(nx-n.r,ny-n.r,n.r*2,n.r*2);
  }
  for(const st of stars){
    ctx.globalAlpha=(.35+.65*Math.abs(Math.sin(t*st.sp+st.ph)))*st.z;
    ctx.fillStyle='#cfe4ff';ctx.fillRect(st.x,st.y,st.z*1.8,st.z*1.8);
  }
  ctx.globalAlpha=1;
  /* shake */
  if(shake>0)ctx.translate(rand(-shake,shake)*.5,rand(-shake,shake)*.5);
  /* bricks */
  for(const b of bricks)if(b.alive)drawBrick(b);
  /* capsules */
  const capCol={W:'#ffd23f',L:'#ff4f69',T:'#3ddc97',S:'#4cc9f0',H:'#ff8ad0'};
  const capLetter={W:'W',L:'L',T:'T',S:'S',H:'♥'};
  for(const c of caps){
    ctx.save();ctx.translate(c.x,c.y);ctx.rotate(Math.sin(c.wob)*.15);
    ctx.shadowColor=capCol[c.type];ctx.shadowBlur=12;
    ctx.fillStyle=capCol[c.type];rr(ctx,-17,-9,34,18,9);ctx.fill();
    ctx.shadowBlur=0;ctx.fillStyle='rgba(255,255,255,.35)';rr(ctx,-14,-7,28,6,3);ctx.fill();
    ctx.fillStyle='#0b1020';ctx.font="700 12px "+DFONT;ctx.textAlign='center';ctx.textBaseline='middle';
    ctx.fillText(capLetter[c.type],0,1);ctx.restore();
  }
  /* bolts */
  ctx.fillStyle='#ff6b81';ctx.shadowColor='#ff4f69';ctx.shadowBlur=10;
  for(const L of bolts){ctx.fillRect(L.x-1.5,L.y-12,3,13);}ctx.shadowBlur=0;
  /* particles */
  for(const p of parts){
    const a=clamp(p.life/p.max,0,1);
    if(p.type==='shard'){ctx.save();ctx.translate(p.x,p.y);ctx.rotate(p.rot);
      ctx.globalAlpha=a;ctx.fillStyle=p.col;ctx.fillRect(-p.size/2,-p.size/2,p.size,p.size*.7);ctx.restore();}
    else{ctx.globalAlpha=a;ctx.fillStyle=p.col;
      ctx.beginPath();ctx.arc(p.x,p.y,p.size,0,TAU);ctx.fill();}
  }
  ctx.globalAlpha=1;
  /* balls */
  for(const b of balls){
    for(let i=0;i<b.trail.length;i++){const tr=b.trail[i],f=(i+1)/b.trail.length;
      ctx.globalAlpha=f*.3;ctx.fillStyle='#9be8ff';
      ctx.beginPath();ctx.arc(tr.x,tr.y,b.r*f,0,TAU);ctx.fill();}
    ctx.globalAlpha=1;ctx.shadowColor='#4cc9f0';ctx.shadowBlur=16;
    ctx.fillStyle='#eafaff';ctx.beginPath();ctx.arc(b.x,b.y,b.r,0,TAU);ctx.fill();
    ctx.shadowBlur=0;ctx.fillStyle='rgba(255,255,255,.9)';
    ctx.beginPath();ctx.arc(b.x-2,b.y-2,2.4,0,TAU);ctx.fill();
  }
  /* paddle */
  {
    const sq=1-paddle.squash*.35,ph=PH*sq,py=PY+(PH-ph);
    ctx.shadowColor='#4cc9f0';ctx.shadowBlur=14+paddle.flash*22;
    const pg=ctx.createLinearGradient(0,py,0,py+ph);
    pg.addColorStop(0,'#a5f3ff');pg.addColorStop(.45,'#37b6e9');pg.addColorStop(1,'#155a86');
    ctx.fillStyle=pg;rr(ctx,paddle.x,py,paddle.w,ph,ph/2);ctx.fill();
    ctx.shadowBlur=0;
    if(effects.laser>0){ctx.fillStyle='#ff4f69';ctx.shadowColor='#ff4f69';ctx.shadowBlur=8;
      ctx.fillRect(paddle.x+5,py-5,6,5);ctx.fillRect(paddle.x+paddle.w-11,py-5,6,5);ctx.shadowBlur=0;}
    if(paddle.flash>0){ctx.fillStyle=`rgba(255,255,255,${paddle.flash*.5})`;
      rr(ctx,paddle.x,py,paddle.w,ph,ph/2);ctx.fill();}
  }
  /* popups */
  ctx.textAlign='center';ctx.textBaseline='middle';
  for(const p of pops){
    ctx.globalAlpha=clamp(p.life/p.max*1.4,0,1);
    ctx.font=(p.big?'700 17px ':'700 13px ')+DFONT;
    ctx.fillStyle='#0b1020';ctx.fillText(p.t,p.x+1,p.y+1);
    ctx.fillStyle=p.col;ctx.fillText(p.t,p.x,p.y);
  }
  ctx.globalAlpha=1;
  /* combo */
  if(combo>=2&&(state==='play'||state==='serve')){
    const multi=Math.min(6,1+Math.floor(combo/4));
    ctx.save();ctx.translate(44,72);ctx.scale(1+comboPulse*.35,1+comboPulse*.35);
    ctx.font='900 16px '+DFONT;ctx.textAlign='left';
    ctx.fillStyle='#0b1020';ctx.fillText(`COMBO ×${multi}`,2,2);
    ctx.fillStyle='#ffd23f';ctx.fillText(`COMBO ×${multi}`,0,0);
    ctx.font='700 10px ui-monospace,Menlo,monospace';ctx.fillStyle='#c9a227';
    ctx.fillText(combo+' HITS',2,14);ctx.restore();
  }
  /* effect pills */
  {
    const defs=[['WIDE',effects.wide,12,'#ffd23f'],['LASER',effects.laser,10,'#ff4f69'],['SLOW-MO',effects.slow,8,'#4cc9f0']];
    const act=defs.filter(d=>d[1]>0);
    let totW=act.reduce((a,d)=>a+Math.max(64,ctx.measureText(d[0]).width+26)+10,0)-10;
    let x=W/2-totW/2;
    for(const d of act){const w=pill(x,60,`${d[0]} ${Math.ceil(d[1])}s`,d[3],d[1]/d[2]);x+=w+10;}
  }
  /* banners + hints */
  if(bannerT>0&&state!=='title'){
    const e=2.3-bannerT;let a=1;
    if(e<.3)a=e/.3;else if(bannerT<.4)a=bannerT/.4;
    const sc=1+Math.max(0,.3-e)*1.6;
    ctx.save();ctx.globalAlpha=a;ctx.translate(W/2,215);ctx.scale(sc,sc);
    ctx.textAlign='center';ctx.font='900 46px '+DFONT;
    ctx.fillStyle='#0b1020';ctx.fillText(bannerMain,3,3);
    ctx.fillStyle='#eaf3ff';ctx.fillText(bannerMain,0,0);
    ctx.font='700 15px ui-monospace,Menlo,monospace';ctx.fillStyle='#ffd23f';
    ctx.fillText('— '+bannerSub+' —',0,30);ctx.restore();
  }
  if(state==='clear'){
    const a=clamp(clearT*3,0,1);
    ctx.save();ctx.globalAlpha=a;ctx.textAlign='center';
    ctx.font='900 44px '+DFONT;ctx.fillStyle='#0b1020';ctx.fillText('SECTOR CLEAR',W/2+3,223);
    ctx.fillStyle='#3ddc97';ctx.fillText('SECTOR CLEAR',W/2,220);
    ctx.font='700 16px ui-monospace,Menlo,monospace';ctx.fillStyle='#ffd23f';
    ctx.fillText('BONUS +'+levelBonus.toLocaleString('en-US'),W/2,252);ctx.restore();
  }
  if(state==='serve'&&bannerT<=.4&&loseCd<=0&&Math.sin(t*6)>-.3){
    ctx.font='700 12px ui-monospace,Menlo,monospace';ctx.textAlign='center';
    ctx.fillStyle='#8fa7cc';ctx.fillText('SPACE / CLICK TO LAUNCH',W/2,PY-30);
  }
  ctx.setTransform(s,0,0,s,0,0);
  if(flashA>0){ctx.fillStyle=flashC+flashA+')';ctx.fillRect(0,0,W,H);}
}

/* ============================ input ============================ */
function primary(){
  ensureAudio();
  if(state==='title'){hideOv(ovTitle);reset();state='serve';return;}
  if(state==='over'||state==='win'){hideOv(ovOver);hideOv(ovWin);reset();state='serve';return;}
  if(state==='serve'){launch();return;}
  if(state==='play'){fireLaser();return;}
}
window.addEventListener('keydown',e=>{
  const k=e.key.toLowerCase();ensureAudio();
  if([' ','arrowleft','arrowright','arrowup','arrowdown'].includes(k))e.preventDefault();
  if(k==='arrowleft'||k==='a')keys.l=1;
  if(k==='arrowright'||k==='d')keys.r=1;
  if(k===' '||k==='enter')primary();
  if(k==='m')toggleMute();
  if(k==='p'&&(state==='play'||state==='serve'||state==='paused')){
    if(state==='paused'){state=balls[0]&&balls[0].stuck?'serve':'play';hideOv(ovPause);}
    else{state='paused';showOv(ovPause);}
  }
});
window.addEventListener('keyup',e=>{
  const k=e.key.toLowerCase();
  if(k==='arrowleft'||k==='a')keys.l=0;
  if(k==='arrowright'||k==='d')keys.r=0;
});
stage.addEventListener('pointermove',e=>{
  const r=cv.getBoundingClientRect();
  mouseX=(e.clientX-r.left)/r.width*W;mouseOn=true;
});
stage.addEventListener('pointerdown',e=>{
  const r=cv.getBoundingClientRect();
  mouseX=(e.clientX-r.left)/r.width*W;mouseOn=true;primary();
});
muteBtn.addEventListener('pointerdown',e=>e.stopPropagation());
muteBtn.addEventListener('click',e=>{e.stopPropagation();ensureAudio();toggleMute();});
function toggleMute(){muted=!muted;muteBtn.textContent=muted?'♪ OFF':'♪ ON';}

/* ============================ boot ============================ */
let viewScale=1;
function fit(){
  const sc=clamp(Math.min((innerWidth-28)/W,(innerHeight-92)/H),.35,1.5);
  stage.style.width=(W*sc)+'px';stage.style.height=(H*sc)+'px';
  stage.style.fontSize=(16*sc)+'px';
  const dpr=Math.min(window.devicePixelRatio||1,2);
  cv.width=Math.max(2,Math.round(W*sc*dpr));cv.height=Math.max(2,Math.round(H*sc*dpr));
  cv._sc=sc*dpr;viewScale=sc*dpr;
}
addEventListener('resize',fit);
cv.style.cursor='crosshair';

reset();state='title';spawnAttractBall();
hiTitle.textContent=hi.toLocaleString('en-US');updateHUD();
fit();

let last=performance.now();
function frame(t){
  const dt=Math.min((t-last)/1000,.033);last=t;
  update(dt,t/1000);render(t/1000);
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
</script>
</body>
</html>

Compare with

Qwen3.8 Max (0902): other attempts