<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://www.pandoraburo.ru/" xml:lang="ru">
  <id>https://www.pandoraburo.ru/tanki-ot-sebya-testiruy-igru</id>
  <link href="https://www.pandoraburo.ru/tanki-ot-sebya-testiruy-igru.xml" rel="self"/>
  <title/>
  <subtitle type="html">
&lt;html lang="ru"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"&gt;
&lt;title&gt;БРОНЕНОСЕЦ v2 · Живая сталь&lt;/title&gt;
&lt;style&gt;
:root{--ph:#39ff8a;--phd:#0d4a28;--ph2:#a6ffc7;--rd:#ff5340;--am:#ffb400;--cy:#4fd6e0;--mg:#b06cff;--bg:#05080a;--frame:#1a1f1c;--px:'Courier New',monospace;--disp:'Courier New',monospace}
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%}
body{font-family:var(--px);background:#000;color:var(--ph);overflow:hidden;display:flex;align-items:center;justify-content:center;background:radial-gradient(ellipse at center,#0a1410 0%,#000 80%)}
.monitor{position:relative;width:min(96vw,980px);aspect-ratio:960/640;background:var(--frame);border-radius:36px;padding:28px 28px 38px;box-shadow:0 40px 90px rgba(0,0,0,.8),inset 0 0 0 3px #0a0f0c,0 0 0 2px #2a332e}
.monitor::before{content:"БРОНЕНОСЕЦ · МОДЕЛЬ ИМ-03";position:absolute;top:10px;left:50%;transform:translateX(-50%);font-size:10px;letter-spacing:4px;color:#4a5f4a}
.screen{position:relative;width:100%;height:100%;background:#02080a;border:3px solid var(--phd);border-radius:18px;overflow:hidden;box-shadow:0 0 40px rgba(57,255,138,.35),inset 0 0 80px rgba(57,255,138,.12),inset 0 0 0 6px #000,inset 0 0 0 8px #0a1a10}
.screen::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:40;background:repeating-linear-gradient(0deg,rgba(0,0,0,.25) 0 2px,transparent 2px 4px);mix-blend-mode:multiply}
.screen::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:41;opacity:.08;background:radial-gradient(ellipse at 30% 20%,rgba(255,255,255,.5),transparent 50%)}
canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.hud{position:absolute;top:8px;left:12px;right:12px;z-index:30;display:flex;justify-content:space-between;align-items:center;gap:8px;font-size:12px;color:var(--ph);text-shadow:0 0 6px var(--ph);pointer-events:none;flex-wrap:wrap}
.hud .blk{border:1px solid var(--phd);padding:5px 9px;border-radius:4px;background:rgba(5,15,10,.6);backdrop-filter:blur(2px)}
.hud b{color:var(--ph2)}
.lives{display:flex;gap:4px}
.life{width:18px;height:12px;background:var(--ph);box-shadow:0 0 6px var(--ph);clip-path:polygon(0 30%,30% 0,70% 0,100% 30%,100% 100%,70% 85%,50% 100%,30% 85%,0 100%);animation:pop .3s cubic-bezier(.3,1.8,.4,1)}
@keyframes pop{from{transform:scale(0)}}
.mult{color:var(--am);text-shadow:0 0 6px var(--am);animation:blink .5s steps(2) infinite}
@keyframes blink{50%{opacity:.4}}
.foes{display:flex;gap:2px;flex-wrap:wrap;max-width:120px}
.foe{width:6px;height:6px;background:var(--rd);box-shadow:0 0 4px var(--rd)}
.bossbar{position:absolute;top:34px;left:10%;right:10%;height:8px;border:1px solid var(--phd);border-radius:4px;background:rgba(0,0,0,.6);z-index:30;display:none;overflow:hidden}
.bossbar.on{display:block}
.bossbar i{display:block;height:100%;background:linear-gradient(90deg,var(--rd),var(--am),var(--cy));border-radius:2px;transition:width .15s;box-shadow:0 0 10px var(--rd)}
.minimap{position:absolute;top:44px;right:12px;z-index:31;background:rgba(5,15,10,.7);border:1px solid var(--phd);border-radius:6px;padding:5px 7px;backdrop-filter:blur(2px);display:flex;gap:4px;align-items:center;min-height:26px}
.minimap .ml{font-size:9px;color:#4a5f4a;margin-right:5px;letter-spacing:1px}
.minimap .mi{width:10px;height:10px;border-radius:2px;animation:mpop .4s}
@keyframes mpop{from{transform:scale(0) rotate(-90deg)}}
.ov{position:absolute;inset:0;z-index:50;display:none;align-items:center;justify-content:center;flex-direction:column;gap:14px;text-align:center;padding:20px;background:rgba(0,0,0,.75);backdrop-filter:blur(3px)}
.ov.show{display:flex;animation:fadeIn .4s}
@keyframes fadeIn{from{opacity:0;transform:scale(.97)}}
.ov h1{font-size:clamp(28px,5vw,54px);color:var(--ph);text-shadow:0 0 18px var(--ph),0 0 36px var(--ph);letter-spacing:3px;animation:glitch 3s infinite}
@keyframes glitch{0%,94%,100%{transform:translate(0,0)}95%{transform:translate(-2px,1px)}97%{transform:translate(2px,-1px)}}
.ov h2{font-size:clamp(22px,4vw,38px);color:var(--ph);text-shadow:0 0 14px var(--ph);letter-spacing:2px}
.ov h2.rd{color:var(--rd);text-shadow:0 0 18px var(--rd)}
.ov p{color:var(--ph2);font-size:14px;max-width:48ch;line-height:1.5}
.ov p b{color:var(--am);text-shadow:0 0 6px var(--am)}
.btn{font-family:var(--px);font-size:13px;background:transparent;color:var(--ph);border:2px solid var(--ph);padding:14px 24px;border-radius:6px;cursor:pointer;text-shadow:0 0 6px var(--ph);box-shadow:0 0 12px rgba(57,255,138,.4);transition:.2s;letter-spacing:2px}
.btn:hover{background:var(--ph);color:#02080a;text-shadow:none;box-shadow:0 0 24px var(--ph)}
.btn:active{transform:translateY(2px)}
.btn.alt{border-color:var(--am);color:var(--am);text-shadow:0 0 6px var(--am);box-shadow:0 0 12px rgba(255,180,0,.4)}
.btn.alt:hover{background:var(--am);color:#02080a}
.btn.cy{border-color:var(--cy);color:var(--cy);text-shadow:0 0 6px var(--cy);box-shadow:0 0 12px rgba(79,214,224,.4)}
.btn.cy:hover{background:var(--cy);color:#02080a}
.btn.mg{border-color:var(--mg);color:var(--mg);text-shadow:0 0 6px var(--mg);box-shadow:0 0 12px rgba(176,108,255,.4)}
.btn.mg:hover{background:var(--mg);color:#02080a}
@keyframes brn-pulse{0%,100%{box-shadow:0 0 12px rgba(57,255,138,.4)}50%{box-shadow:0 0 46px rgba(57,255,138,.95);transform:scale(1.06)}}
.brn-pulse{animation:brn-pulse 1.2s infinite}
.keys{display:flex;gap:6px;flex-wrap:wrap;justify-content:center}
.keys span{border:1px solid var(--phd);padding:6px 10px;border-radius:4px;font-size:10px;color:var(--ph2)}
.stat{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:8px;max-width:500px;width:100%}
.stat div{border:1px solid var(--phd);padding:10px;border-radius:4px;background:rgba(5,15,10,.5)}
.stat b{display:block;font-size:22px;color:var(--am);text-shadow:0 0 8px var(--am)}
.stat span{font-size:10px;color:var(--ph2)}
.cd{font-size:48px;color:var(--am);text-shadow:0 0 18px var(--am);animation:pulse 1s infinite}
@keyframes pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.12)}}
#fade{position:absolute;inset:0;background:#000;opacity:0;pointer-events:none;z-index:45;transition:opacity .8s}
#fade.on{opacity:1}
#fxred,#fxgold,#fxblue,#fxpickup{position:absolute;inset:0;pointer-events:none;opacity:0;z-index:42}
#fxred{background:radial-gradient(ellipse at center,transparent 40%,rgba(255,40,20,.55))}
#fxgold{background:radial-gradient(ellipse at center,transparent 40%,rgba(255,220,80,.5))}
#fxblue{background:radial-gradient(ellipse at center,transparent 40%,rgba(79,214,224,.5))}
#fxpickup{background:radial-gradient(ellipse at center,transparent 20%,rgba(255,255,255,.4))}
#fxred.go,#fxgold.go,#fxblue.go{animation:vflash .55s ease-out}
#fxpickup.go{animation:vflashP .35s ease-out}
@keyframes vflash{0%{opacity:1}100%{opacity:0}}
@keyframes vflashP{0%{opacity:.8}100%{opacity:0}}
#joy{position:absolute;width:100px;height:100px;border-radius:50%;border:2px solid var(--ph);background:rgba(57,255,138,.08);z-index:44;display:none;backdrop-filter:blur(2px)}
#stick{position:absolute;left:50%;top:50%;width:40px;height:40px;margin:-20px 0 0 -20px;border-radius:50%;background:var(--ph);box-shadow:0 0 10px var(--ph)}
#fire{position:absolute;right:16px;bottom:16px;width:88px;height:88px;border-radius:50%;background:rgba(255,83,64,.15);border:2px solid var(--rd);color:var(--rd);font-family:var(--px);font-size:12px;z-index:44;display:none;text-shadow:0 0 6px var(--rd);box-shadow:0 0 14px rgba(255,83,64,.5);backdrop-filter:blur(2px)}
#fire:active{transform:scale(.92);background:rgba(255,83,64,.3)}
body.touch #joy,body.touch #fire{display:block}
.combo-display{position:absolute;bottom:60px;left:50%;transform:translateX(-50%);z-index:35;font-size:22px;font-weight:800;color:var(--am);text-shadow:0 0 20px var(--am),0 0 40px rgba(255,180,0,.3);pointer-events:none;opacity:0;transition:opacity .3s}
.combo-display.show{opacity:1}
.combo-display .num{font-size:36px}
.combo-display .label{font-size:14px;letter-spacing:3px;color:var(--ph2)}
.ach-wrap{position:absolute;top:56px;left:12px;z-index:36;display:flex;flex-direction:column;gap:6px;pointer-events:none;max-width:240px}
.ach{background:rgba(10,20,14,.85);border:1px solid var(--am);border-radius:6px;padding:8px 12px;color:var(--ph2);font-size:11px;backdrop-filter:blur(3px);box-shadow:0 0 14px rgba(255,180,0,.4);animation:achIn .4s cubic-bezier(.3,1.8,.4,1),achOut .4s ease-in 3s forwards;display:flex;gap:8px;align-items:center}
.ach .ico{font-size:20px;filter:drop-shadow(0 0 6px var(--am))}
.ach .tit{font-weight:800;color:var(--am);display:block;letter-spacing:1px}
@keyframes achIn{from{transform:translateX(-120%);opacity:0}}
@keyframes achOut{to{transform:translateX(-120%);opacity:0}}
.achlist{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:6px;max-width:600px;width:100%;margin-top:10px}
.achlist div{border:1px solid var(--phd);padding:7px 10px;border-radius:5px;background:rgba(5,15,10,.4);font-size:11px;color:#4a5f4a;display:flex;gap:8px;align-items:center}
.achlist div.on{border-color:var(--am);color:var(--ph2);background:rgba(255,180,0,.08)}
.achlist .ico{font-size:18px}
.toplist{margin-top:16px;max-width:460px;width:100%}
.toplist h3{font-size:12px;color:var(--ph);margin-bottom:8px;letter-spacing:2px}
.toprow{display:flex;justify-content:space-between;padding:6px 10px;border-bottom:1px dashed var(--phd);font-size:12px;color:var(--ph2)}
.toprow:first-child{color:var(--am)}
.toprow b{font-weight:800}
.toprow .medal{margin-right:8px}
.musbtn{position:absolute;bottom:12px;left:12px;z-index:43;font-size:10px;padding:7px 12px;background:rgba(5,15,10,.7);border:1px solid var(--phd);color:var(--ph2);border-radius:6px;cursor:pointer;backdrop-filter:blur(2px);letter-spacing:1px}
.musbtn.on{border-color:var(--cy);color:var(--cy);box-shadow:0 0 10px rgba(79,214,224,.4)}
.arena-tag{position:absolute;top:8px;left:50%;transform:translateX(-50%);z-index:32;font-size:10px;padding:4px 12px;border:1px solid var(--phd);border-radius:4px;background:rgba(5,15,10,.7);color:var(--ph2);letter-spacing:2px;backdrop-filter:blur(2px);pointer-events:none}
@media(max-width:720px){.monitor{border-radius:18px;padding:14px 14px 22px}.screen{border-radius:10px}.minimap{top:38px;right:8px}.ach-wrap{top:50px;max-width:180px}}
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms !important;transition-duration:.01ms !important}}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class="monitor"&gt;
  &lt;div class="screen"&gt;
    &lt;canvas id="cv" width="960" height="608"&gt;&lt;/canvas&gt;
    &lt;div class="arena-tag" id="arenaTag"&gt;ПОЛИГОН&lt;/div&gt;
    &lt;div class="hud"&gt;
      &lt;div class="blk"&gt;❤ &lt;span class="lives" id="hudLives"&gt;&lt;/span&gt;&lt;/div&gt;
      &lt;div class="blk"&gt;РАУНД &lt;b id="hudRound"&gt;1&lt;/b&gt;&lt;/div&gt;
      &lt;div class="blk"&gt;? &lt;b id="hudScore"&gt;0&lt;/b&gt;&lt;span class="mult" id="hudMult" style="display:none;margin-left:6px"&gt;×2&lt;/span&gt;&lt;/div&gt;
      &lt;div class="blk"&gt;? &lt;div class="foes" id="hudFoes"&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="bossbar" id="bossbar"&gt;&lt;i id="bossfill"&gt;&lt;/i&gt;&lt;/div&gt;
    &lt;div class="minimap" id="minimap"&gt;&lt;span class="ml"&gt;ОЧЕРЕДЬ&lt;/span&gt;&lt;/div&gt;
    &lt;div class="combo-display" id="comboDisplay"&gt;&lt;span class="num" id="comboNum"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;span class="label"&gt;СЕРИЯ&lt;/span&gt;&lt;/div&gt;
    &lt;div class="ach-wrap" id="achWrap"&gt;&lt;/div&gt;

    &lt;div id="fxred"&gt;&lt;/div&gt;&lt;div id="fxgold"&gt;&lt;/div&gt;&lt;div id="fxblue"&gt;&lt;/div&gt;&lt;div id="fxpickup"&gt;&lt;/div&gt;
    &lt;div id="fade"&gt;&lt;/div&gt;

    &lt;div class="ov show" id="menuOv"&gt;
      &lt;h1&gt;БРОНЕНОСЕЦ v2&lt;/h1&gt;
      &lt;h2 style="font-size:16px;color:var(--ph2)"&gt;⚡ ЖИВАЯ СТАЛЬ ⚡&lt;/h2&gt;
      &lt;p&gt;Уничтожай врагов — &lt;b&gt;+1 жизнь&lt;/b&gt;. Каждый 5-й раунд — &lt;b&gt;БОСС&lt;/b&gt;. Каждая 5-я карта — &lt;b&gt;новая арена&lt;/b&gt;.&lt;br /&gt;Серия ×2. Достижения. Synthwave.&lt;/p&gt;
      &lt;div class="keys"&gt;&lt;span&gt;WASD / стрелки — ехать&lt;/span&gt;&lt;span&gt;ПРОБЕЛ — огонь&lt;/span&gt;&lt;span&gt;P — пауза&lt;/span&gt;&lt;/div&gt;
      &lt;div class="toplist" id="toplist"&gt;&lt;h3&gt;? ТОП-3 РЕКОРДОВ&lt;/h3&gt;&lt;div id="toprows"&gt;&lt;/div&gt;&lt;/div&gt;
      &lt;button class="btn brn-pulse" id="startBtn" style="font-size:20px;padding:20px 48px;letter-spacing:4px"&gt;▶ В БОЙ&lt;/button&gt;
      &lt;div style="color:#a6ffc7;font-size:13px;letter-spacing:3px;margin-top:-6px"&gt;НАЖМИ, ЧТОБЫ НАЧАТЬ БОЙ&lt;/div&gt;
      &lt;button class="btn mg" id="achBtn" style="padding:8px 16px;font-size:10px"&gt;? ДОСТИЖЕНИЯ&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class="ov" id="introOv"&gt;&lt;h2 id="introT"&gt;РАУНД 1&lt;/h2&gt;&lt;p id="introP"&gt;&lt;/p&gt;&lt;/div&gt;
    &lt;div class="ov" id="endOv"&gt;&lt;h2 id="endT"&gt;РАУНД ЗАЧИЩЕН ✦&lt;/h2&gt;&lt;p id="endP"&gt;&lt;/p&gt;&lt;div class="cd" id="endCd"&gt;3&lt;/div&gt;&lt;/div&gt;

    &lt;div class="ov" id="overOv"&gt;
      &lt;h2 class="rd"&gt;? ТАНК ПОДБИТ&lt;/h2&gt;
      &lt;div class="stat"&gt;
        &lt;div&gt;&lt;b id="sK"&gt;0&lt;/b&gt;&lt;span&gt;уничтожено&lt;/span&gt;&lt;/div&gt;
        &lt;div&gt;&lt;b id="sA"&gt;0%&lt;/b&gt;&lt;span&gt;точность&lt;/span&gt;&lt;/div&gt;
        &lt;div&gt;&lt;b id="sR"&gt;1&lt;/b&gt;&lt;span&gt;раунд&lt;/span&gt;&lt;/div&gt;
        &lt;div&gt;&lt;b id="sS"&gt;0&lt;/b&gt;&lt;span&gt;очки&lt;/span&gt;&lt;/div&gt;
        &lt;div&gt;&lt;b id="sB"&gt;0&lt;/b&gt;&lt;span&gt;рекорд&lt;/span&gt;&lt;/div&gt;
      &lt;/div&gt;
      &lt;div style="display:flex;gap:10px;flex-wrap:wrap;justify-content:center"&gt;
        &lt;button class="btn alt" id="againBtn"&gt;⟳ ЗАНОВО&lt;/button&gt;
        &lt;button class="btn" id="menuBtn"&gt;МЕНЮ&lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;div class="ov" id="pauseOv"&gt;&lt;h2&gt;⏸ ПАУЗА&lt;/h2&gt;&lt;button class="btn cy" id="resBtn"&gt;▶ ПРОДОЛЖИТЬ&lt;/button&gt;&lt;/div&gt;

    &lt;div class="ov" id="achOv"&gt;
      &lt;h2 style="font-size:24px"&gt;? ДОСТИЖЕНИЯ&lt;/h2&gt;
      &lt;p style="font-size:12px"&gt;Открыто &lt;b id="achCnt"&gt;0&lt;/b&gt;/9&lt;/p&gt;
      &lt;div class="achlist" id="achList"&gt;&lt;/div&gt;
      &lt;button class="btn" id="achClose" style="margin-top:14px"&gt;✖ ЗАКРЫТЬ&lt;/button&gt;
    &lt;/div&gt;

    &lt;div id="joy"&gt;&lt;div id="stick"&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;button id="fire"&gt;? ОГОНЬ&lt;/button&gt;
    &lt;button class="musbtn" id="musbtn"&gt;♫ МУЗЫКА&lt;/button&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
(function(){
"use strict";
const RM=matchMedia('(prefers-reduced-motion: reduce)').matches;
const W=960,H=608,CS=32,GW=30,GH=19;
const cv=document.getElementById('cv'),ctx=cv.getContext('2d');
(function(){const d=Math.min(2,devicePixelRatio||1);cv.width=W*d;cv.height=H*d;ctx.setTransform(d,0,0,d,0,0);})();
function $(s){return document.querySelector(s)}
const R=(a,b)=&gt;a+Math.random()*(b-a),RI=(a,b)=&gt;Math.floor(R(a,b+1)),clamp=(v,a,b)=&gt;v&lt;a?a:v&gt;b?b:v,hyp=(x,y)=&gt;Math.sqrt(x*x+y*y),angDiff=(a,b)=&gt;{let d=(b-a)%(Math.PI*2);if(d&gt;Math.PI)d-=Math.PI*2;if(d&lt;-Math.PI)d+=Math.PI*2;return d};
function rr(x,y,w,h,r){ctx.beginPath();ctx.moveTo(x+r,y);ctx.arcTo(x+w,y,x+w,y+h,r);ctx.arcTo(x+w,y+h,x,y+h,r);ctx.arcTo(x,y+h,x,y,r);ctx.arcTo(x,y,x+w,y,r);ctx.closePath()}

/* ══════ АРЕНЫ ══════ */
const ARENAS=[
 {name:'ПОЛИГОН',bg1:'#0a1810',bg2:'#02080a',gridC:'rgba(57,255,138,.06)',brick:'#0d4a28',brickBrd:'#39ff8a',steel:'#1a3a2a',steelBrd:'#39ff8a',decoC:'rgba(57,255,138,',dustC:'#0d4a28',starC:'#a6ffc7'},
 {name:'ПУСТЫНЯ',bg1:'#2a1f0e',bg2:'#0f0a02',gridC:'rgba(255,180,90,.06)',brick:'#6a4820',brickBrd:'#d4a060',steel:'#4a3018',steelBrd:'#b87a40',decoC:'rgba(220,160,80,',dustC:'#5a3a10',starC:'#ffe27a'},
 {name:'ГОРОД',bg1:'#151922',bg2:'#05070c',gridC:'rgba(120,160,200,.06)',brick:'#3a3a45',brickBrd:'#7890a0',steel:'#1a2030',steelBrd:'#5a7890',decoC:'rgba(120,160,200,',dustC:'#2a2a35',starC:'#c0d4e0'},
 {name:'БАЗА',bg1:'#1a1018',bg2:'#05020a',gridC:'rgba(255,100,180,.06)',brick:'#4a2038',brickBrd:'#d050a0',steel:'#2a0a20',steelBrd:'#9a3078',decoC:'rgba(255,100,180,',dustC:'#3a1830',starC:'#ffc0e0'}
];
let arenaIdx=0,arena=ARENAS[0];

/* ══════ ЗВУК + МУЗЫКА ══════ */
let AC=null,muted=false,noiseBuf=null,musicOn=false,musicG=null,musicNodes=[];
function ac(){if(!AC){try{AC=new(window.AudioContext||window.webkitAudioContext)();const b=AC.createBuffer(1,AC.sampleRate*0.5,AC.sampleRate),d=b.getChannelData(0);for(let i=0;i&lt;d.length;i++)d[i]=Math.random()*2-1;noiseBuf=b;}catch(e){}}return AC}
function tone(f,d,type,v,f2,dl){if(muted)return;const a=ac();if(!a)return;const t=a.currentTime+(dl||0),o=a.createOscillator(),g=a.createGain();o.type=type||'square';o.frequency.setValueAtTime(f,t);if(f2)o.frequency.exponentialRampToValueAtTime(Math.max(f2,1),t+d);g.gain.setValueAtTime(v||.07,t);g.gain.exponentialRampToValueAtTime(.0001,t+d);o.connect(g);g.connect(a.destination);o.start(t);o.stop(t+d)}
function noiz(d,v,fq,dl){if(muted)return;const a=ac();if(!a||!noiseBuf)return;const t=a.currentTime+(dl||0),s=a.createBufferSource(),g=a.createGain(),f=a.createBiquadFilter();s.buffer=noiseBuf;f.type='lowpass';f.frequency.value=fq||800;g.gain.setValueAtTime(v||.15,t);g.gain.exponentialRampToValueAtTime(.0001,t+d);s.connect(f);f.connect(g);g.connect(a.destination);s.start(t);s.stop(t+d)}
const SFX={
  shoot:()=&gt;{tone(300,.08,'square',.05,90);noiz(.05,.04,3500)},
  eshoot:()=&gt;tone(200,.09,'square',.035,70),
  boom:s=&gt;{noiz(.45*s,.22,500);tone(100,.4,'triangle',.16,30)},
  brick:()=&gt;noiz(.12,.1,1200),
  ping:()=&gt;tone(1300,.05,'square',.04,900),
  hurt:()=&gt;{noiz(.3,.2,700);tone(160,.25,'sawtooth',.12,60)},
  life:()=&gt;{tone(660,.09,'triangle',.08);tone(990,.12,'triangle',.08,0,.09)},
  pick:()=&gt;{tone(700,.07,'square',.06);tone(1050,.09,'square',.06,0,.07)},
  laser:()=&gt;tone(220,.8,'sawtooth',.03,1100),
  fanfare:()=&gt;[523,659,784,1047].forEach((f,i)=&gt;tone(f,.16,'square',.08,0,i*.12)),
  over:()=&gt;tone(300,.5,'sawtooth',.1,60),
  bossAlert:()=&gt;{tone(180,.6,'sawtooth',.08,80);setTimeout(()=&gt;tone(240,.6,'sawtooth',.08,80),300)},
  ach:()=&gt;{tone(880,.08,'triangle',.09);setTimeout(()=&gt;tone(1320,.1,'triangle',.09),80);setTimeout(()=&gt;tone(1760,.14,'triangle',.09),180)}
};
const BASS=[55,55,73.42,73.42,65.41,65.41,82.41,82.41];
const ARP=[220,330,440,660,550,440,330,220,246,370,494,740,587,494,370,246];
function startMusic(){
  if(musicOn||muted)return;
  const a=ac();if(!a)return;
  musicG=a.createGain();musicG.gain.value=.07;
  musicG.connect(a.destination);
  musicOn=true;
  const bpm=108,beat=60/bpm;
  let step=0,t0=a.currentTime+.1;
  function sched(){
    if(!musicOn)return;
    const now=a.currentTime;
    while(t0&lt;now+.5){
      const bStep=step%8;
      const bo=a.createOscillator(),bg=a.createGain();
      bo.type='sawtooth';bo.frequency.value=BASS[bStep];
      bg.gain.setValueAtTime(0,t0);bg.gain.linearRampToValueAtTime(.18,t0+.01);bg.gain.exponentialRampToValueAtTime(.001,t0+beat*.9);
      const bf=a.createBiquadFilter();bf.type='lowpass';bf.frequency.value=300;
      bo.connect(bf);bf.connect(bg);bg.connect(musicG);bo.start(t0);bo.stop(t0+beat);
      const aStep=step%16;
      const ao=a.createOscillator(),ag=a.createGain();
      ao.type='triangle';ao.frequency.value=ARP[aStep];
      ag.gain.setValueAtTime(0,t0);ag.gain.linearRampToValueAtTime(.08,t0+.005);ag.gain.exponentialRampToValueAtTime(.001,t0+beat*.45);
      ao.connect(ag);ag.connect(musicG);ao.start(t0);ao.stop(t0+beat*.5);
      t0+=beat/2;step++;
    }
    musicNodes.push(setTimeout(sched,80));
  }
  sched();
}
function stopMusic(){
  musicOn=false;musicNodes.forEach(clearTimeout);musicNodes=[];
  if(musicG){try{musicG.gain.exponentialRampToValueAtTime(.0001,ac().currentTime+.3)}catch(e){}}
}
$('#musbtn').addEventListener('click',function(){
  if(!musicOn){startMusic();this.classList.add('on');this.textContent='♫ ON';}
  else{stopMusic();this.classList.remove('on');this.textContent='♫ OFF';}
});

/* ══════ ДОСТИЖЕНИЯ ══════ */
const ACHS={
  firstBlood:{t:'ПЕРВАЯ КРОВЬ',i:'?',d:'Уничтожь первого врага'},
  bossKill:{t:'ЦАРЕУБИЙЦА',i:'?',d:'Убей босса'},
  streak10:{t:'ЖНЕЦ',i:'?',d:'Серия из 10 убийств'},
  nineLives:{t:'КОШАЧИЙ ЦАРЬ',i:'?',d:'Накопи 9 жизней'},
  accuracy80:{t:'СНАЙПЕР',i:'?',d:'Точность 80%+ за игру'},
  round10:{t:'МАРАФОНЕЦ',i:'?',d:'Дойди до 10 раунда'},
  round20:{t:'ЛЕГЕНДА',i:'⭐',d:'Дойди до 20 раунда'},
  score5k:{t:'5000',i:'?',d:'Набери 5000 очков'},
  allArenas:{t:'СТРАННИК',i:'?️',d:'Побывай на всех 4 аренах'}
};
let achUnlocked={};
try{achUnlocked=JSON.parse(localStorage.getItem('bron_ach')||'{}')}catch(e){achUnlocked={}}
function saveAch(){try{localStorage.setItem('bron_ach',JSON.stringify(achUnlocked))}catch(e){}}
function unlockAch(id){
  if(achUnlocked[id])return;
  achUnlocked[id]=Date.now();saveAch();
  const a=ACHS[id];
  const el=document.createElement('div');el.className='ach';
  el.innerHTML='&lt;span class="ico"&gt;'+a.i+'&lt;/span&gt;&lt;div&gt;&lt;span class="tit"&gt;'+a.t+'&lt;/span&gt;&lt;span&gt;'+a.d+'&lt;/span&gt;&lt;/div&gt;';
  $('#achWrap').appendChild(el);
  SFX.ach();
  setTimeout(()=&gt;el.remove(),4000);
  renderAchList();
}
function renderAchList(){
  const list=$('#achList');list.innerHTML='';
  let cnt=0;
  Object.keys(ACHS).forEach(id=&gt;{
    const a=ACHS[id],on=!!achUnlocked[id];if(on)cnt++;
    const d=document.createElement('div');if(on)d.classList.add('on');
    d.innerHTML='&lt;span class="ico"&gt;'+(on?a.i:'?')+'&lt;/span&gt;&lt;div&gt;&lt;b style="color:'+(on?'var(--am)':'#4a5f4a')+'"&gt;'+a.t+'&lt;/b&gt;&lt;br&gt;'+a.d+'&lt;/div&gt;';
    list.appendChild(d);
  });
  $('#achCnt').textContent=cnt;
}
$('#achBtn').addEventListener('click',()=&gt;{renderAchList();$('#menuOv').classList.remove('show');$('#achOv').classList.add('show')});
$('#achClose').addEventListener('click',()=&gt;{$('#achOv').classList.remove('show');$('#menuOv').classList.add('show')});

/* ══════ ТОП-3 ══════ */
let topScores=[];
try{topScores=JSON.parse(localStorage.getItem('bron_top')||'[]')}catch(e){topScores=[]}
function saveTop(){try{localStorage.setItem('bron_top',JSON.stringify(topScores))}catch(e){}}
function addTopScore(s,k,r){
  topScores.push({s,k,r,d:new Date().toLocaleDateString('ru-RU',{day:'2-digit',month:'2-digit'})});
  topScores.sort((a,b)=&gt;b.s-a.s);topScores=topScores.slice(0,3);saveTop();renderTopList();
}
function renderTopList(){
  const rows=$('#toprows');rows.innerHTML='';
  if(!topScores.length){rows.innerHTML='&lt;div class="toprow" style="justify-content:center;color:#4a5f4a"&gt;рекордов пока нет&lt;/div&gt;';return;}
  const medals=['?','?','?'];
  topScores.forEach((t,i)=&gt;{
    const d=document.createElement('div');d.className='toprow';
    d.innerHTML='&lt;span class="medal"&gt;'+medals[i]+'&lt;/span&gt;&lt;span&gt;&lt;b&gt;'+t.s+'&lt;/b&gt; очк · Р'+t.r+' · уб. '+t.k+'&lt;/span&gt;&lt;span&gt;'+t.d+'&lt;/span&gt;';
    rows.appendChild(d);
  });
}
renderAchList();renderTopList();

/* ══════ СОСТОЯНИЕ ══════ */
let state='menu',tSec=0;
let grid=new Uint8Array(GW*GH),deco=[],bushes=[],craters=[],stars=[];
for(let i=0;i&lt;120;i++)stars.push({x:R(0,W),y:R(0,H),r:R(.3,1.8),b:R(.2,.8),s:R(.02,.08)});
let bullets=[],parts=[],rings=[],floats=[],warns=[],pickups=[];
let enemies=[],bossPending=false,queue=[];
let spawnT=0;
let round=1,score=0,lives=3,kills=0,shots=0,hitsN=0,best=0;
try{best=topScores.length?topScores[0].s:0}catch(e){}
let streakN=0,lastKill=-99,streakOn=false,dblT=0;
let shake=0,recoil=0,shakeMul=RM?0:1,pMul=RM?.35:1;
let keys={},firing=false,joyX=0,joyY=0;
let endTimer=null;
let visitedArenas=new Set();

/* ИСПРАВЛЕНО: добавлен barrel:24 — ствол виден и пули летят корректно */
const P={x:W/2,y:H-80,a:-Math.PI/2,r:15,barrel:24,sp:0,cd:0,inv:0,flash:0,rec:0,shield:false,rapidT:0,dead:false,dustT:0,engineT:0};
function curMult(){return(streakOn?2:1)*(dblT&gt;0?2:1)}

const PAL={
  player:{tr:'#0d4a28',b1:'#39ff8a',b2:'#0d8a42',tu:'#a6ffc7',bar:'#0d4a28'},
  scout:{tr:'#4a3a10',b1:'#ffd23f',b2:'#b88a00',tu:'#ffe27a',bar:'#6a4a00'},
  assault:{tr:'#4a1512',b1:'#ff6a4d',b2:'#c92c14',tu:'#ff8d6e',bar:'#7a1a0a'},
  heavy:{tr:'#2a1a4a',b1:'#b06cff',b2:'#6a3aaa',tu:'#d4a4ff',bar:'#3a1a6a'},
  sniper:{tr:'#0f2a3a',b1:'#4fd6e0',b2:'#1a7a9e',tu:'#a6eff5',bar:'#0d4a60'},
  boss:{tr:'#2a0a0a',b1:'#ff4040',b2:'#8a1010',tu:'#ff8080',bar:'#4a0505'}
};
const ETYPES={
  scout:{hp:1,sp:115,turn:3.4,cool:2.1,bs:250,spread:.3,range:540,score:100,r:13,barrel:20},
  assault:{hp:1,sp:82,turn:2.6,cool:1.55,bs:275,spread:.22,range:470,score:150,r:15,barrel:24},
  heavy:{hp:3,sp:46,turn:1.7,cool:2.5,bs:300,spread:.07,range:640,score:300,r:19,barrel:28},
  sniper:{hp:1,sp:62,turn:2.2,cool:3.1,bs:390,spread:.02,range:820,score:250,r:13,barrel:32},
  boss:{hp:14,sp:40,turn:1.3,cool:2.1,bs:285,spread:.12,range:760,score:1000,r:34,barrel:46}
};

function cellAt(x,y){const cx=(x/CS)|0,cy=(y/CS)|0;if(cx&lt;0||cy&lt;0||cx&gt;=GW||cy&gt;=GH)return 2;return grid[cy*GW+cx]}
function setc(x,y,v){if(x&gt;=0&amp;&amp;y&gt;=0&amp;&amp;x&lt;GW&amp;&amp;y&lt;GH)grid[y*GW+x]=v}
function clearZone(px,py,rad){for(let y=0;y&lt;GH;y++)for(let x=0;x&lt;GW;x++){const dx=x*CS+16-px,dy=y*CS+16-py;if(hyp(dx,dy)&lt;rad)grid[y*GW+x]=0}}
const SPAWNS=[[70,70],[W-70,70],[70,H-70],[W-70,H-70],[W/2,64]];

function genArena(){
  grid.fill(0);deco=[];bushes=[];
  for(let i=0;i&lt;40;i++)deco.push({x:R(0,W),y:R(0,H),r:R(14,50),a:R(.02,.06),ph:R(0,6.28),s:R(.01,.04)});
  for(let k=0;k&lt;5;k++){const y=RI(3,GH-6),x=RI(2,7),len=RI(2,4),vert=Math.random()&lt;.35;
    for(let j=0;j&lt;len;j++){if(vert){setc(x,y+j,1);setc(GW-1-x,y+j,1)}else{setc(x+j,y,1);setc(GW-1-x-j,y,1)}}}
  const spots=[[5,4],[9,9],[5,14]];
  for(let s2=0;s2&lt;spots.length;s2++){if(Math.random()&lt;.8){const sx=spots[s2][0],sy=spots[s2][1];
    setc(sx,sy,2);setc(sx+1,sy,2);setc(sx,sy+1,2);setc(sx+1,sy+1,2);
    setc(GW-2-sx,sy,2);setc(GW-1-sx,sy,2);setc(GW-2-sx,sy+1,2);setc(GW-1-sx,sy+1,2);}}
  for(let b=0;b&lt;5;b++)bushes.push({x:R(80,W-80),y:R(80,H-80),r:R(26,40),s:R(0,7)});
  SPAWNS.forEach(p=&gt;clearZone(p[0],p[1],80));
  clearZone(W/2,H-80,90);
}
function circleBlocked(x,y,r){
  const x0=Math.max(0,((x-r)/CS)|0),x1=Math.min(GW-1,((x+r)/CS)|0),y0=Math.max(0,((y-r)/CS)|0),y1=Math.min(GH-1,((y+r)/CS)|0);
  for(let cy=y0;cy&lt;=y1;cy++)for(let cx=x0;cx&lt;=x1;cx++){if(grid[cy*GW+cx]){const rx=cx*CS,ry=cy*CS,nx=clamp(x,rx,rx+CS),ny=clamp(y,ry,ry+CS);if(hyp(x-nx,y-ny)&lt;r)return true;}}
  return false;
}
function los(x1,y1,x2,y2){const d=hyp(x2-x1,y2-y1),n=(d/14)|0;for(let i=1;i&lt;n;i++){const x=x1+(x2-x1)*i/n,y=y1+(y2-y1)*i/n;if(cellAt(x,y)&gt;0)return false}return true}

function addShake(v){shake=Math.min(20,shake+v*shakeMul)}
function addRecoil(v){recoil=Math.min(8,recoil+v*shakeMul)}
function flash(dom){const el=$(dom);el.classList.remove('go');void el.offsetWidth;el.classList.add('go')}

/* ИСПРАВЛЕННАЯ ФУНКЦИЯ FADE — callback вызывается и при скрытии */
function fade(show,cb){
  const f=$('#fade');
  if(show){
    f.classList.add('on');
    setTimeout(cb||function(){},800);
  }else{
    setTimeout(()=&gt;{
      f.classList.remove('on');
      if(cb)cb();
    },50);
  }
}

function floatTxt(x,y,txt,col,big){floats.push({x,y,txt,col:col||'#a6ffc7',t:1.2,big});if(floats.length&gt;24)floats.shift()}
function ringFx(x,y,c,r0){rings.push({x,y,r:r0||8,vr:RM?120:260,a:.9,col:c})}
function part(p){parts.push(p);if(parts.length&gt;360)parts.shift()}

function boom(x,y,s,col,extra){
  const n=Math.round((16*s+4)*pMul);
  for(let i=0;i&lt;n;i++){const a=R(0,6.28),v=R(30,190)*s;part({tp:'fire',x,y,vx:Math.cos(a)*v,vy:Math.sin(a)*v,t:R(.25,.5),m:.5,r:R(3,7)*s,c:i%3?col:'#a6ffc7'})}
  for(let i=0;i&lt;8*s*pMul;i++){const a=R(0,6.28);part({tp:'smoke',x:x+R(-8,8),y:y+R(-8,8),vx:Math.cos(a)*R(10,40),vy:Math.sin(a)*R(10,40)-20,t:R(.5,.9),m:.9,r:R(6,12)*s})}
  for(let i=0;i&lt;7*s*pMul;i++){const a=R(0,6.28);part({tp:'deb',x,y,vx:Math.cos(a)*R(60,240)*s,vy:Math.sin(a)*R(60,240)*s,t:R(.4,.8),m:.8,r:R(2,4),a2:R(0,6.28),vr:R(-8,8),c:col})}
  if(extra){for(let i=0;i&lt;12*s*pMul;i++){const a=R(0,6.28),v=R(50,160)*s;part({tp:'spark',x,y,vx:Math.cos(a)*v,vy:Math.sin(a)*v,t:R(.15,.35),m:.35,c:extra})}}
  part({tp:'flash',x,y,t:.12,m:.12,r:26*s});
  ringFx(x,y,col,10);
  if(s&gt;1){craters.push({x,y,r:R(14,22)*Math.min(s,1.4)});if(craters.length&gt;60)craters.shift()}
  addShake(5*s);SFX.boom(Math.min(s,1.4));
  if(s&gt;1.5)flash('#fxgold');
}
function turretFly(e){part({tp:'tur',x:e.x,y:e.y,vx:R(-90,90),vy:R(-120,-30),t:1,m:1,r:e.r*.55,a2:e.a,vr:R(-7,7),pal:PAL[e.type]||PAL.assault})}
function sparks(x,y,n){for(let i=0;i&lt;n*pMul;i++){const a=R(0,6.28);part({tp:'spark',x,y,vx:Math.cos(a)*R(80,260),vy:Math.sin(a)*R(80,260),t:R(.15,.3),m:.3,c:'#a6ffc7'})}}
function dust(x,y){part({tp:'dust',x,y,vx:R(-8,8),vy:R(-8,8),t:.5,m:.5,r:R(3,6)})}

let lastLives=-1,lastScore=-1,lastFoes=-1,lastRound=-1,lastQueue='';
function syncHUD(){
  if(lives!==lastLives){lastLives=lives;let h='';for(let i=0;i&lt;lives;i++)h+='&lt;span class="life"&gt;&lt;/span&gt;';$('#hudLives').innerHTML=h}
  if(score!==lastScore){lastScore=score;$('#hudScore').textContent=score}
  $('#hudRound').textContent=round;
  $('#hudMult').style.display=(streakOn||dblT&gt;0)?'inline':'none';
  $('#hudMult').textContent='×'+curMult();
  const rem=queue.length+warns.length+enemies.length;
  if(rem!==lastFoes){lastFoes=rem;let f='';for(let i=0;i&lt;rem;i++)f+='&lt;span class="foe"&gt;&lt;/span&gt;';$('#hudFoes').innerHTML=f||'&lt;span style="color:var(--ph);font-size:9px"&gt;ЧИСТО&lt;/span&gt;'}
  const boss=enemies.find(e=&gt;e.type==='boss');
  $('#bossbar').classList.toggle('on',!!boss);
  if(boss)$('#bossfill').style.width=(boss.hp/boss.maxHp*100)+'%';
  const qstr=queue.slice(0,5).join(',')+(queue.length&gt;5?'+'+(queue.length-5):'');
  if(qstr!==lastQueue){
    lastQueue=qstr;
    const mm=$('#minimap');mm.innerHTML='&lt;span class="ml"&gt;ОЧЕРЕДЬ&lt;/span&gt;';
    queue.slice(0,5).forEach(t=&gt;{
      const m=document.createElement('span');m.className='mi';
      const c=PAL[t]?PAL[t].b1:'#fff';
      m.style.background=c;m.style.boxShadow='0 0 6px '+c;
      mm.appendChild(m);
    });
    if(queue.length&gt;5){const more=document.createElement('span');more.className='ml';more.textContent='+'+(queue.length-5);mm.appendChild(more)}
  }
}

function fireBullet(t,foe,spread,bs,big){
  const a=t.a+R(-spread,spread),sp=bs;
  bullets.push({x:t.x+Math.cos(a)*(t.r+t.barrel),y:t.y+Math.sin(a)*(t.r+t.barrel),vx:Math.cos(a)*sp,vy:Math.sin(a)*sp,foe,r:big?6:4.2,big});
  t.flash=.07;t.rec=1;
  if(!foe)addRecoil(3);
}
function playerFire(){if(P.cd&gt;0||P.dead)return;P.cd=P.rapidT&gt;0?.22:.45;fireBullet(P,false,.03,430);shots++;SFX.shoot()}

function hitPlayer(){
  if(P.inv&gt;0||P.dead||state!=='playing')return;
  if(P.shield){P.shield=false;P.inv=1;ringFx(P.x,P.y,'#4fd6e0',20);SFX.ping();floatTxt(P.x,P.y-30,'? ЩИТ ПОГАС','#4fd6e0');flash('#fxblue');return}
  lives--;P.inv=2;flash('#fxred');addShake(13);SFX.hurt();
  boom(P.x,P.y,.7,'#ff8d6e','#ffb400');
  floatTxt(P.x,P.y-34,'−1 ❤','#ff5340');syncHUD();
  if(lives&lt;=0){P.dead=true;turretFly({x:P.x,y:P.y,r:P.r,a:P.a,type:'player'});boom(P.x,P.y,2,'#39ff8a','#a6ffc7');state='dying';SFX.over();setTimeout(showGameOver,1400)}
}
function killEnemy(e){
  e.dead=true;kills++;
  if(kills===1)unlockAch('firstBlood');
  const mult=curMult(),pts=e.score*mult;score+=pts;
  if(score&gt;=5000)unlockAch('score5k');
  const extra=e.type==='boss'?'#ffb400':null;
  boom(e.x,e.y,e.type==='boss'?2.4:1.1,PAL[e.type].b1,extra);
  turretFly(e);
  floatTxt(e.x,e.y-30,'+'+pts,'#a6ffc7',e.type==='boss');
  if(e.type==='boss')unlockAch('bossKill');
  if(lives&lt;9){lives++;flash('#fxgold');SFX.life();floatTxt(e.x,e.y-52,'+1 ЖИЗНЬ ✚','#a6ffc7');if(lives===9)unlockAch('nineLives')}
  if(tSec-lastKill&lt;4)streakN++;else streakN=1;
  lastKill=tSec;
  if(streakN&gt;=3&amp;&amp;!streakOn){streakOn=true;floatTxt(P.x,P.y-40,'? СЕРИЯ ×2!','#ffb400',true);flash('#fxgold')}
  if(streakN&gt;=10)unlockAch('streak10');
  updateComboDisplay();rollPickup(e);syncHUD();
  if(state==='playing'&amp;&amp;!queue.length&amp;&amp;!warns.length&amp;&amp;!enemies.some(o=&gt;!o.dead)){state='clearing';setTimeout(roundEnd,900)}
}
function updateComboDisplay(){
  const el=$('#comboDisplay'),num=$('#comboNum');
  if(streakN&gt;=3){num.textContent=streakN;el.classList.add('show')}else{el.classList.remove('show')}
}
function damageEnemy(e,b){if(e.spawnT&gt;0)return;e.hp--;hitsN++;sparks(b.x,b.y,6);SFX.ping();if(e.hp&lt;=0)killEnemy(e)}
function rollPickup(e){
  const ch=e.type==='boss'?1:.2;if(Math.random()&gt;ch)return;
  const r=Math.random(),tp=r&lt;.3?'shield':r&lt;.6?'rapid':r&lt;.9?'double':'life';
  pickups.push({x:clamp(e.x,40,W-40),y:clamp(e.y,40,H-40),tp,t:8,ph:R(0,6)})
}
function buildQueue(n){
  queue=[];
  if(n%5===0){bossPending=true;for(let i=0;i&lt;4;i++)queue.push(Math.random()&lt;.5?'scout':'assault');return}
  const total=Math.min(4+2*(n-1),16);
  for(let i=0;i&lt;total;i++){let r=Math.random(),t;if(n&lt;2)t=r&lt;.55?'scout':'assault';
    else if(n&lt;4)t=r&lt;.4?'scout':r&lt;.75?'assault':'heavy';
    else t=r&lt;.34?'scout':r&lt;.62?'assault':r&lt;.82?'heavy':'sniper';
    queue.push(t)}
}
function hideAll(){['menuOv','introOv','endOv','overOv','pauseOv','achOv'].forEach(id=&gt;$('#'+id).classList.remove('show'))}

function roundIntro(n){
  arenaIdx=Math.floor((n-1)/5)%ARENAS.length;
  arena=ARENAS[arenaIdx];
  visitedArenas.add(arenaIdx);
  if(visitedArenas.size===4)unlockAch('allArenas');
  $('#arenaTag').textContent=arena.name;
  fade(true,()=&gt;{
    round=n;buildQueue(n);genArena();
    bullets=[];pickups=[];warns=[];enemies=[];parts=[];rings=[];
    P.x=W/2;P.y=H-80;P.a=-Math.PI/2;P.inv=1.5;P.cd=0;P.dead=false;P.rapidT=0;dblT=0;streakOn=false;streakN=0;
    updateComboDisplay();spawnT=1;
    const en=queue.length+(bossPending?1:0);
    $('#introT').textContent='РАУНД '+n+(n%5===0?' · БОСС':'');
    $('#introP').innerHTML=(n%5===0?'⚠ &lt;b&gt;БОСС&lt;/b&gt; на арене! ':'')+'Арена: &lt;b&gt;'+arena.name+'&lt;/b&gt; · Врагов: &lt;b&gt;'+en+'&lt;/b&gt;'+(n%3===0?' · в конце &lt;b&gt;+1 жизнь&lt;/b&gt;':'');
    hideAll();$('#introOv').classList.add('show');syncHUD();
    setTimeout(()=&gt;{fade(false,()=&gt;{$('#introOv').classList.remove('show');state='playing'})},1400);
  });
}
function roundEnd(){
  if(state!=='clearing')return;state='roundend';SFX.fanfare();
  if(round&gt;=10)unlockAch('round10');if(round&gt;=20)unlockAch('round20');
  const bonus=round%3===0&amp;&amp;lives&lt;9;
  if(round%3===0){lives=Math.min(9,lives+1);flash('#fxgold');syncHUD()}
  $('#endT').textContent='РАУНД '+round+' ЗАЧИЩЕН ✦';
  $('#endP').innerHTML='Жизни: &lt;b&gt;'+lives+'&lt;/b&gt;'+(bonus?' · бонус &lt;b&gt;+1&lt;/b&gt;!':'')+' · Счёт: &lt;b&gt;'+score+'&lt;/b&gt;';
  hideAll();$('#endOv').classList.add('show');
  let c=3;$('#endCd').textContent=c;
  clearInterval(endTimer);endTimer=setInterval(()=&gt;{c--;if(c&gt;0)$('#endCd').textContent=c;else{clearInterval(endTimer);roundIntro(round+1)}},1000);
}
function showGameOver(){
  state='gameover';
  if(shots&amp;&amp;hitsN/shots&gt;=.8&amp;&amp;kills&gt;=5)unlockAch('accuracy80');
  if(score&gt;best){best=score}
  addTopScore(score,kills,round);
  $('#sK').textContent=kills;$('#sA').textContent=(shots?Math.round(hitsN/shots*100):0)+'%';
  $('#sR').textContent=round;$('#sS').textContent=score;$('#sB').textContent=best;
  hideAll();$('#overOv').classList.add('show');
  stopMusic();
}
function fullReset(){score=0;lives=3;kills=0;shots=0;hitsN=0;craters=[];lastLives=-1;lastScore=-1;lastFoes=-1;lastQueue='';streakN=0;streakOn=false;dblT=0;visitedArenas=new Set();updateComboDisplay();renderTopList();roundIntro(1);if(!muted)startMusic()}

function fieldCount(){return enemies.length+warns.length}
function updSpawn(dt){
  if(bossPending){bossPending=false;warns.push({x:W/2,y:96,t:1.3,type:'boss'});SFX.bossAlert();flash('#fxred')}
  spawnT-=dt;
  const cap=round%5===0?5:4;
  if(spawnT&lt;=0&amp;&amp;queue.length&amp;&amp;fieldCount()&lt;cap){
    const type=queue.shift(),pts=SPAWNS.filter(p=&gt;hyp(p[0]-P.x,p[1]-P.y)&gt;200);
    const pt=(pts.length?pts:SPAWNS)[RI(0,(pts.length?pts:SPAWNS).length-1)];
    warns.push({x:pt[0],y:pt[1],t:.85,type});
    spawnT=Math.max(.75,1.5-(round-1)*.07);
  }
  for(let i=warns.length-1;i&gt;=0;i--){const w=warns[i];w.t-=dt;if(w.t&lt;=0){warns.splice(i,1);spawnEnemy(w.type,w.x,w.y)}}
}
function spawnEnemy(type,x,y){
  const T=ETYPES[type],sc=Math.min(1.5,1+(round-1)*.05);
  const e={type,x,y,a:Math.atan2(P.y-y,P.x-x),r:T.r,hp:type==='boss'?12+round:T.hp,sp:T.sp*sc,turn:T.turn,cool:R(.5,T.cool),cool2:1.4,bs:T.bs,spread:T.spread,range:T.range,score:T.score,barrel:T.barrel,flash:0,rec:0,spawnT:.35,dead:false,avoidT:0,avoidDir:1,orbitDir:Math.random()&lt;.5?1:-1,orbitT:R(2,5),aiming:false,aimT:0,aimX:0,aimY:0,dodgeCd:0,dodgeT:0,dodgeDir:1,dustT:0,phase:0,phaseTimer:0};
  e.maxHp=e.hp;
  enemies.push(e);ringFx(x,y,PAL[type].b1,e.r+6);noiz(.15,.06,900);
  if(type==='boss'){for(let i=0;i&lt;6;i++){const a=i/6*Math.PI*2;part({tp:'fire',x:x+Math.cos(a)*20,y:y+Math.sin(a)*20,vx:Math.cos(a)*30,vy:Math.sin(a)*30,t:.5,m:.5,r:4,c:'#ff4040'})}}
}
function moveEnt(t,dt,spd){
  let nx=t.x+Math.cos(t.a)*spd*dt,ny=t.y+Math.sin(t.a)*spd*dt,moved=0;
  if(!circleBlocked(nx,t.y,t.r)){t.x=nx;moved+=Math.abs(spd*dt)}
  if(!circleBlocked(t.x,ny,t.r)){t.y=ny;moved+=Math.abs(spd*dt)}
  t.x=clamp(t.x,t.r+4,W-t.r-4);t.y=clamp(t.y,t.r+4,H-t.r-4);return moved;
}
function updEnemy(e,dt){
  if(e.spawnT&gt;0){e.spawnT-=dt;return}
  e.flash=Math.max(0,e.flash-dt);e.rec=Math.max(0,e.rec-dt*4);e.cool-=dt;e.dodgeCd-=dt;e.dodgeT-=dt;
  if(e.type==='boss'){e.phaseTimer-=dt;if(e.phaseTimer&lt;=0){e.phase=(e.phase+1)%3;e.phaseTimer=3+R(0,2);
    if(e.phase===1)floatTxt(e.x,e.y-40,'⚡ РЕЖИМ ОГНЯ','#ffb400',true);
    if(e.phase===2)floatTxt(e.x,e.y-40,'? УСКОРЕНИЕ','#4fd6e0',true)}}
  const dx=P.x-e.x,dy=P.y-e.y,dist=hyp(dx,dy),ang=Math.atan2(dy,dx);
  if(e.dodgeCd&lt;=0&amp;&amp;e.type!=='boss'){for(let i=0;i&lt;bullets.length;i++){const b=bullets[i];if(b.foe)continue;const bd=hyp(b.x-e.x,b.y-e.y);
    if(bd&lt;110){const movingToward=((e.x-b.x)*b.vx+(e.y-b.y)*b.vy)&gt;0;if(movingToward&amp;&amp;Math.random()&lt;(e.type==='scout'?.75:e.type==='sniper'?.5:.4)){e.dodgeT=.35;e.dodgeDir=Math.random()&lt;.5?1:-1;e.dodgeCd=1.1;break}}}}
  if(e.dodgeT&gt;0){e.a+=e.dodgeDir*e.turn*1.4*dt;moveEnt(e,dt,e.sp);return}
  let desired=ang,moveF=1;
  if(e.type==='scout'){e.orbitT-=dt;if(e.orbitT&lt;=0){e.orbitDir*=-1;e.orbitT=R(2.5,5)}
    if(dist&gt;240)desired=ang;else if(dist&lt;160)desired=ang+Math.PI;else desired=ang+e.orbitDir*Math.PI/2;
    if(e.cool&lt;=0&amp;&amp;Math.abs(angDiff(e.a,ang))&lt;.5&amp;&amp;dist&lt;e.range){fireBullet(e,true,e.spread,e.bs);e.cool=ETYPES.scout.cool*Math.max(.6,1-(round-1)*.04);SFX.eshoot()}}
  else if(e.type==='assault'){if(dist&gt;160)desired=ang;else desired=ang+e.orbitDir*.9;
    e.orbitT-=dt;if(e.orbitT&lt;=0){e.orbitDir*=-1;e.orbitT=R(2,4)}
    moveF=dist&lt;110?.4:1;
    if(e.cool&lt;=0&amp;&amp;Math.abs(angDiff(e.a,ang))&lt;.45&amp;&amp;dist&lt;e.range){fireBullet(e,true,e.spread,e.bs);e.cool=ETYPES.assault.cool*Math.max(.6,1-(round-1)*.04);SFX.eshoot()}}
  else if(e.type==='heavy'){if(dist&gt;280)desired=ang;else moveF=0;
    if(e.cool&lt;=0&amp;&amp;Math.abs(angDiff(e.a,ang))&lt;.3&amp;&amp;dist&lt;e.range){fireBullet(e,true,e.spread,e.bs,true);e.cool=ETYPES.heavy.cool*Math.max(.6,1-(round-1)*.04);SFX.eshoot();addShake(2)}}
  else if(e.type==='sniper'){if(e.aiming){e.aimT-=dt;e.aimX=P.x;e.aimY=P.y;e.a+=angDiff(e.a,ang)*4*dt;
    if(e.aimT&lt;=0){e.aiming=false;fireBullet(e,true,e.spread,e.bs);e.cool=ETYPES.sniper.cool*Math.max(.6,1-(round-1)*.04)}return}
    if(dist&gt;360)desired=ang;else if(dist&lt;240)desired=ang+Math.PI;else moveF=.3;
    if(e.cool&lt;=0&amp;&amp;dist&lt;e.range&amp;&amp;los(e.x,e.y,P.x,P.y)){e.aiming=true;e.aimT=1;e.aimX=P.x;e.aimY=P.y;SFX.laser();moveF=0}}
  else if(e.type==='boss'){const phaseSpeed=e.phase===2?1.6:1;
    if(dist&gt;250)desired=ang;else if(dist&lt;170)desired=ang+Math.PI;else desired=ang+.7;
    moveF=.7*phaseSpeed;const fireRate=e.phase===1?.7:1;
    if(e.cool&lt;=0&amp;&amp;Math.abs(angDiff(e.a,ang))&lt;.5){const count=e.phase===1?5:3;
      for(let s=0;s&lt;count;s++){const spread=(s-(count-1)/2)*.15;fireBullet(e,true,spread,e.bs)}
      e.cool=ETYPES.boss.cool*fireRate;SFX.eshoot();addShake(4)}
    e.cool2-=dt;if(e.cool2&lt;=0&amp;&amp;Math.abs(angDiff(e.a,ang))&lt;.35){fireBullet(e,true,.03,e.bs+60,true);e.cool2=1.5;SFX.eshoot()}}
  if(e.avoidT&gt;0){e.avoidT-=dt;desired=e.a+e.avoidDir*1.2;moveF=1}
  e.a+=clamp(angDiff(e.a,desired),-e.turn*dt,e.turn*dt);
  if(moveF&gt;0){const intent=e.sp*moveF*dt,moved=moveEnt(e,dt,e.sp*moveF);
    if(moved&lt;intent*.3&amp;&amp;e.avoidT&lt;=0){e.avoidT=.7;e.avoidDir=Math.random()&lt;.5?1:-1}
    e.dustT-=dt;if(e.dustT&lt;=0){dust(e.x-Math.cos(e.a)*e.r,e.y-Math.sin(e.a)*e.r);e.dustT=.12}}
  for(let j=0;j&lt;enemies.length;j++){const o=enemies[j];if(o===e||o.dead)continue;const d2=hyp(o.x-e.x,o.y-e.y),min=e.r+o.r+4;
    if(d2&lt;min&amp;&amp;d2&gt;0){const push=(min-d2)/2,ax=(e.x-o.x)/d2,ay=(e.y-o.y)/d2;
      if(!circleBlocked(e.x+ax*push,e.y+ay*push,e.r)){e.x+=ax*push;e.y+=ay*push}}}
}

function update(dt){
  tSec+=dt;
  P.cd-=dt;P.inv=Math.max(0,P.inv-dt);P.flash=Math.max(0,P.flash-dt);P.rec=Math.max(0,P.rec-dt*4);
  P.rapidT=Math.max(0,P.rapidT-dt);dblT=Math.max(0,dblT-dt);
  recoil=Math.max(0,recoil-dt*24);
  if(streakOn&amp;&amp;tSec-lastKill&gt;4){streakOn=false;updateComboDisplay()}
  if(state==='playing'||state==='clearing'){
    if(!P.dead){
      let fwd=0,turn=0;
      if(keys.KeyW||keys.ArrowUp)fwd=1;if(keys.KeyS||keys.ArrowDown)fwd=-1;
      if(keys.KeyA||keys.ArrowLeft)turn=-1;if(keys.KeyD||keys.ArrowRight)turn=1;
      if(Math.abs(joyX)&gt;.15||Math.abs(joyY)&gt;.15){turn=joyX;fwd=-joyY}
      P.a+=turn*3.2*dt;
      const sp=fwd&gt;0?155:fwd&lt;0?-95:0;
      if(sp){const moved=moveEnt(P,dt,sp);P.dustT-=dt;if(P.dustT&lt;=0&amp;&amp;moved&gt;0){dust(P.x-Math.cos(P.a)*P.r,P.y-Math.sin(P.a)*P.r);P.dustT=.09}
        if(moved&gt;10){P.engineT+=dt;if(P.engineT&gt;.04){P.engineT=0;for(let i=0;i&lt;2;i++){const a=P.a+Math.PI+R(-.5,.5),v=R(10,25);
          part({tp:'smoke',x:P.x-Math.cos(P.a)*P.r+R(-4,4),y:P.y-Math.sin(P.a)*P.r+R(-4,4),vx:Math.cos(a)*v,vy:Math.sin(a)*v-R(2,8),t:R(.3,.5),m:.5,r:R(3,6)})}}}}
      if(firing||keys.Space)playerFire();
    }
    if(state==='playing')updSpawn(dt);
    for(let i=enemies.length-1;i&gt;=0;i--){const e=enemies[i];if(e.dead){enemies.splice(i,1);continue}updEnemy(e,dt)}
    for(let i=bullets.length-1;i&gt;=0;i--){
      const b=bullets[i];b.x+=b.vx*dt;b.y+=b.vy*dt;let del=false;
      if(b.x&lt;4||b.y&lt;4||b.x&gt;W-4||b.y&gt;H-4){del=true}else{
        const v=cellAt(b.x,b.y);
        if(v===1){grid[((b.y/CS)|0)*GW+((b.x/CS)|0)]=0;SFX.brick();sparks(b.x,b.y,5);
          for(let k=0;k&lt;5*pMul;k++)part({tp:'deb',x:b.x,y:b.y,vx:R(-90,90),vy:R(-90,90),t:.5,m:.5,r:R(2,3.5),a2:R(0,6.28),vr:R(-9,9),c:arena.brick});
          craters.push({x:b.x,y:b.y,r:9});if(craters.length&gt;60)craters.shift();del=true}
        else if(v===2){sparks(b.x,b.y,7);SFX.ping();del=true}}
      if(!del){if(b.foe){if(!P.dead&amp;&amp;hyp(b.x-P.x,b.y-P.y)&lt;P.r+b.r){hitPlayer();del=true}}
        else{for(let j=0;j&lt;enemies.length;j++){const en=enemies[j];if(en.spawnT&gt;0)continue;if(hyp(b.x-en.x,b.y-en.y)&lt;en.r+b.r){damageEnemy(en,b);del=true;break}}}}
      if(del)bullets.splice(i,1);
    }
    for(let i=pickups.length-1;i&gt;=0;i--){const pk=pickups[i];pk.t-=dt;pk.ph+=dt*4;
      if(pk.t&lt;=0){pickups.splice(i,1);continue}
      if(!P.dead&amp;&amp;hyp(pk.x-P.x,pk.y-P.y)&lt;P.r+18){
        let txt='',col='#a6ffc7';
        if(pk.tp==='shield'){P.shield=true;txt='? ЩИТ';col='#4fd6e0';flash('#fxblue')}
        else if(pk.tp==='rapid'){P.rapidT=8;txt='⚡ ОГОНЬ ×2';col='#a6ffc7';flash('#fxgold')}
        else if(pk.tp==='double'){dblT=10;txt='×2 ОЧКИ';col='#ffb400';flash('#fxgold')}
        else{lives=Math.min(9,lives+1);txt='+1 ЖИЗНЬ ✚';col='#39ff8a';flash('#fxgold')}
        floatTxt(pk.x,pk.y-24,txt,col);SFX.pick();ringFx(pk.x,pk.y,col,14);flash('#fxpickup');
        pickups.splice(i,1);syncHUD();
      }}
  }
  for(let i=parts.length-1;i&gt;=0;i--){const p=parts[i];p.t-=dt;if(p.t&lt;=0){parts.splice(i,1);continue}
    p.x+=(p.vx||0)*dt;p.y+=(p.vy||0)*dt;
    if(p.tp==='deb'||p.tp==='tur'){p.vx*=.96;p.vy*=.96;p.a2+=(p.vr||0)*dt}
    if(p.tp==='smoke')p.r+=8*dt}
  for(let i=rings.length-1;i&gt;=0;i--){const r=rings[i];r.r+=r.vr*dt;r.a-=dt*2.2;if(r.a&lt;=0)rings.splice(i,1)}
  for(let i=floats.length-1;i&gt;=0;i--){const f=floats[i];f.t-=dt;f.y-=28*dt;if(f.t&lt;=0)floats.splice(i,1)}
  shake=Math.max(0,shake-dt*30);syncHUD();
}

function drawTank(t,pal,alpha){
  ctx.save();ctx.globalAlpha=alpha===undefined?1:alpha;
  ctx.translate(t.x,t.y);
  ctx.fillStyle='rgba(0,0,0,.4)';ctx.beginPath();ctx.ellipse(2,4,t.r*1.2,t.r*.95,0,0,7);ctx.fill();
  ctx.rotate(t.a);
  const rec=(t.rec||0)*4;
  ctx.fillStyle=pal.tr;rr(-t.r,-t.r-3,t.r*2,7,3);ctx.fill();rr(-t.r,t.r-4,t.r*2,7,3);ctx.fill();
  ctx.fillStyle='rgba(0,0,0,.4)';
  for(let i=-t.r+3;i&lt;t.r-2;i+=6){ctx.fillRect(i,-t.r-2,2,5);ctx.fillRect(i,t.r-3,2,5)}
  const g=ctx.createLinearGradient(0,-t.r,0,t.r);g.addColorStop(0,pal.b1);g.addColorStop(1,pal.b2);
  ctx.fillStyle=g;rr(-t.r,-t.r+3,t.r*2,t.r*2-6,5);ctx.fill();
  ctx.strokeStyle='rgba(0,0,0,.5)';ctx.lineWidth=2;ctx.stroke();
  if(t.type==='heavy'||t.type==='boss'){ctx.fillStyle='rgba(0,0,0,.3)';ctx.fillRect(-t.r+4,-t.r+6,4,t.r*2-12);ctx.fillRect(t.r-8,-t.r+6,4,t.r*2-12)}
  ctx.fillStyle=pal.bar;ctx.fillRect(t.r*.2-2,-3,t.r+t.barrel-rec-t.r*.2+2,6);
  ctx.fillStyle='rgba(255,255,255,.3)';ctx.fillRect(t.r*.2,-3,t.r+t.barrel-rec-t.r*.2,2);
  if(t.rapidT&gt;0&amp;&amp;t===P){ctx.shadowColor='#a6ffc7';ctx.shadowBlur=12}
  const g2=ctx.createRadialGradient(-2,-2,1,0,0,t.r*.6);g2.addColorStop(0,pal.tu);g2.addColorStop(1,pal.b2);
  ctx.fillStyle=g2;ctx.beginPath();ctx.arc(-rec*.4,0,t.r*.58,0,7);ctx.fill();
  ctx.strokeStyle='rgba(0,0,0,.5)';ctx.stroke();ctx.shadowBlur=0;
  ctx.restore();
  if(t.flash&gt;0){
    const mx=t.x+Math.cos(t.a)*(t.r+t.barrel),my=t.y+Math.sin(t.a)*(t.r+t.barrel);
    ctx.save();ctx.translate(mx,my);ctx.rotate(R(0,6.28));
    ctx.fillStyle='rgba(255,255,220,.95)';ctx.shadowColor='#a6ffc7';ctx.shadowBlur=20;
    ctx.beginPath();for(let s=0;s&lt;8;s++){const rr2=s%2?4:11;ctx.lineTo(Math.cos(s*Math.PI/4)*rr2,Math.sin(s*Math.PI/4)*rr2)}
    ctx.closePath();ctx.fill();ctx.restore();
  }
  if(t.maxHp&amp;&amp;t.hp&lt;t.maxHp&amp;&amp;t.type!=='boss'){
    ctx.fillStyle='rgba(0,0,0,.6)';ctx.fillRect(t.x-16,t.y-t.r-14,32,5);
    const hpCol=t.hp/t.maxHp&gt;.5?'#39ff8a':t.hp/t.maxHp&gt;.25?'#ffb400':'#ff5340';
    ctx.fillStyle=hpCol;ctx.fillRect(t.x-15,t.y-t.r-13,30*t.hp/t.maxHp,3);
  }
}

function draw(){
  ctx.save();
  if(shake&gt;0)ctx.translate(R(-shake,shake)*.5,R(-shake,shake)*.5);
  if(recoil&gt;0&amp;&amp;!P.dead){ctx.translate(-Math.cos(P.a)*recoil,-Math.sin(P.a)*recoil)}
  const gg=ctx.createRadialGradient(W/2,H/2,100,W/2,H/2,620);gg.addColorStop(0,arena.bg1);gg.addColorStop(1,arena.bg2);
  ctx.fillStyle=gg;ctx.fillRect(-20,-20,W+40,H+40);
  ctx.strokeStyle=arena.gridC;ctx.lineWidth=1;
  for(let x=0;x&lt;=GW;x++){ctx.beginPath();ctx.moveTo(x*CS,0);ctx.lineTo(x*CS,H);ctx.stroke()}
  for(let y=0;y&lt;=GH;y++){ctx.beginPath();ctx.moveTo(0,y*CS);ctx.lineTo(W,y*CS);ctx.stroke()}
  stars.forEach(s=&gt;{ctx.globalAlpha=s.b*(0.6+0.4*Math.sin(tSec*s.s));ctx.fillStyle=arena.starC;ctx.beginPath();ctx.arc(s.x,s.y,s.r,0,7);ctx.fill()});ctx.globalAlpha=1;
  deco.forEach(d=&gt;{ctx.fillStyle=arena.decoC+(d.a+0.08*Math.sin(tSec*d.s))+')';ctx.beginPath();ctx.ellipse(d.x,d.y,d.r,d.r*.7,0,0,7);ctx.fill()});
  craters.forEach(c=&gt;{ctx.fillStyle='rgba(0,0,0,.5)';ctx.beginPath();ctx.ellipse(c.x,c.y,c.r,c.r*.8,0,0,7);ctx.fill();
    ctx.strokeStyle=arena.decoC+'.2)';ctx.lineWidth=2;ctx.beginPath();ctx.ellipse(c.x,c.y-2,c.r*.8,c.r*.6,0,Math.PI,6.28);ctx.stroke()});
  for(let cy=0;cy&lt;GH;cy++)for(let cx=0;cx&lt;GW;cx++){const v=grid[cy*GW+cx];if(!v)continue;const px=cx*CS,py=cy*CS;
    if(v===1){ctx.fillStyle=arena.brick;ctx.fillRect(px,py,CS,CS);ctx.fillStyle='rgba(0,0,0,.4)';ctx.fillRect(px,py+14,CS,3);ctx.fillRect(px+14,py,3,14);ctx.fillRect(px+6,py+17,3,15);ctx.strokeStyle=arena.brickBrd;ctx.lineWidth=1.5;ctx.strokeRect(px+1,py+1,CS-2,CS-2)}
    else{ctx.fillStyle=arena.steel;ctx.fillRect(px,py,CS,CS);ctx.strokeStyle=arena.steelBrd;ctx.lineWidth=2;ctx.strokeRect(px+1,py+1,CS-2,CS-2);ctx.fillStyle=arena.steelBrd;[[6,6],[26,6],[6,26],[26,26]].forEach(q=&gt;{ctx.beginPath();ctx.arc(px+q[0],py+q[1],2,0,7);ctx.fill()})}}
  warns.forEach(w=&gt;{const pl=.5+.5*Math.sin(tSec*12);ctx.strokeStyle='rgba(255,180,0,'+(0.35+pl*.5)+')';ctx.lineWidth=3;ctx.beginPath();ctx.arc(w.x,w.y,(w.type==='boss'?44:24)+pl*6,0,7);ctx.stroke();ctx.fillStyle='rgba(255,180,0,.9)';ctx.font='700 16px Courier New';ctx.textAlign='center';ctx.fillText('!',w.x,w.y+6)});
  pickups.forEach(pk=&gt;{if(pk.t&lt;2&amp;&amp;Math.floor(pk.t*6)%2)return;const bob=Math.sin(pk.ph)*4;
    ctx.save();ctx.translate(pk.x,pk.y+bob);
    ctx.fillStyle='rgba(0,0,0,.5)';ctx.beginPath();ctx.ellipse(0,14-bob,13,5,0,0,7);ctx.fill();
    const col=pk.tp==='shield'?'#4fd6e0':pk.tp==='rapid'?'#a6ffc7':pk.tp==='double'?'#ffb400':'#39ff8a';
    ctx.shadowColor=col;ctx.shadowBlur=20;ctx.fillStyle=arena.bg2;rr(-14,-14,28,28,7);ctx.fill();
    ctx.strokeStyle=col;ctx.lineWidth=2.5;ctx.stroke();ctx.shadowBlur=0;
    ctx.font='15px Courier New';ctx.textAlign='center';ctx.textBaseline='middle';ctx.fillStyle=col;
    ctx.fillText(pk.tp==='shield'?'?':pk.tp==='rapid'?'⚡':pk.tp==='double'?'×2':'✚',0,1);
    ctx.textBaseline='alphabetic';ctx.restore()});
  enemies.forEach(e=&gt;{if(e.aiming){const mx=e.x+Math.cos(e.a)*(e.r+e.barrel),my=e.y+Math.sin(e.a)*(e.r+e.barrel);
    ctx.save();ctx.strokeStyle='rgba(255,60,50,'+(.45+.4*Math.sin(tSec*20))+')';ctx.lineWidth=2;ctx.setLineDash([7,7]);ctx.lineDashOffset=-tSec*60;
    ctx.beginPath();ctx.moveTo(mx,my);ctx.lineTo(e.aimX,e.aimY);ctx.stroke();ctx.setLineDash([]);
    ctx.beginPath();ctx.arc(e.aimX,e.aimY,9,0,7);ctx.stroke();ctx.restore()}});
  enemies.forEach(e=&gt;{const sc=e.spawnT&gt;0?1-e.spawnT/.35:1;ctx.save();if(sc&lt;1){ctx.translate(e.x,e.y);ctx.scale(sc,sc);ctx.translate(-e.x,-e.y)}drawTank(e,PAL[e.type]);ctx.restore()});
  if(!P.dead){
    const alpha=P.inv&gt;0&amp;&amp;Math.floor(tSec*10)%2?0.35:1;
    drawTank(P,PAL.player,alpha);
    if(P.shield){ctx.save();ctx.strokeStyle='rgba(79,214,224,'+(.6+.3*Math.sin(tSec*6))+')';ctx.lineWidth=3;ctx.shadowColor='#4fd6e0';ctx.shadowBlur=16;ctx.beginPath();ctx.arc(P.x,P.y,P.r+9,0,7);ctx.stroke();ctx.restore()}
    if(P.rapidT&gt;0){ctx.save();ctx.fillStyle='rgba(166,255,199,.15)';ctx.shadowColor='#a6ffc7';ctx.shadowBlur=30;ctx.beginPath();ctx.arc(P.x,P.y,P.r+20,0,7);ctx.fill();ctx.restore()}
  }
  bullets.forEach(b=&gt;{const col=b.foe?(b.big?'#ff4040':'#ffb400'):'#a6ffc7';
    ctx.save();ctx.shadowColor=col;ctx.shadowBlur=16;ctx.fillStyle=col;ctx.beginPath();ctx.arc(b.x,b.y,b.r,0,7);ctx.fill();ctx.shadowBlur=0;
    ctx.globalAlpha=.3;ctx.fillStyle='#fff';ctx.beginPath();ctx.arc(b.x-b.vx*.01,b.y-b.vy*.01,b.r*.5,0,7);ctx.fill();ctx.globalAlpha=1;ctx.restore()});
  bushes.forEach(b=&gt;{ctx.save();ctx.globalAlpha=.65;for(let i=0;i&lt;5;i++){const a=b.s+i*1.26,rr3=b.r*.55,bx=b.x+Math.cos(a)*b.r*.4,by=b.y+Math.sin(a)*b.r*.4;
    ctx.fillStyle=arena.brick;ctx.beginPath();ctx.arc(bx,by,rr3,0,7);ctx.fill()}
    ctx.strokeStyle=arena.brickBrd;ctx.lineWidth=1;for(let i=0;i&lt;5;i++){const a2=b.s+i*1.26,rr4=b.r*.55,bx2=b.x+Math.cos(a2)*b.r*.4,by2=b.y+Math.sin(a2)*b.r*.4;ctx.beginPath();ctx.arc(bx2,by2,rr4,0,7);ctx.stroke()}
    ctx.restore()});
  parts.forEach(p=&gt;{const k=p.t/p.m;
    if(p.tp==='fire'){ctx.globalAlpha=k;ctx.fillStyle=p.c;ctx.shadowColor=p.c;ctx.shadowBlur=10;ctx.beginPath();ctx.arc(p.x,p.y,p.r*k,0,7);ctx.fill();ctx.shadowBlur=0}
    else if(p.tp==='smoke'){ctx.globalAlpha=k*.4;ctx.fillStyle=arena.dustC;ctx.beginPath();ctx.arc(p.x,p.y,p.r,0,7);ctx.fill()}
    else if(p.tp==='deb'){ctx.globalAlpha=k;ctx.save();ctx.translate(p.x,p.y);ctx.rotate(p.a2);ctx.fillStyle=p.c||arena.dustC;ctx.fillRect(-p.r,-p.r,p.r*2,p.r*2);ctx.restore()}
    else if(p.tp==='spark'){ctx.globalAlpha=k;ctx.strokeStyle=p.c;ctx.shadowColor=p.c;ctx.shadowBlur=8;ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(p.x,p.y);ctx.lineTo(p.x-p.vx*.03,p.y-p.vy*.03);ctx.stroke();ctx.shadowBlur=0}
    else if(p.tp==='dust'){ctx.globalAlpha=k*.3;ctx.fillStyle=arena.dustC;ctx.beginPath();ctx.arc(p.x,p.y,p.r,0,7);ctx.fill()}
    else if(p.tp==='flash'){ctx.globalAlpha=k;ctx.fillStyle='rgba(255,255,255,.85)';ctx.shadowColor='#fff';ctx.shadowBlur=30;ctx.beginPath();ctx.arc(p.x,p.y,p.r*k*2,0,7);ctx.fill();ctx.shadowBlur=0}
    else if(p.tp==='tur'){ctx.globalAlpha=Math.min(1,k*1.5);ctx.save();ctx.translate(p.x,p.y);ctx.rotate(p.a2);ctx.fillStyle=p.pal.b2;ctx.beginPath();ctx.arc(0,0,p.r,0,7);ctx.fill();ctx.fillStyle=p.pal.bar;ctx.fillRect(0,-2.5,p.r+9,5);ctx.restore()}
    ctx.globalAlpha=1});
  rings.forEach(r=&gt;{ctx.globalAlpha=Math.max(r.a,0);ctx.strokeStyle=r.col;ctx.shadowColor=r.col;ctx.shadowBlur=12;ctx.lineWidth=3;ctx.beginPath();ctx.arc(r.x,r.y,r.r,0,7);ctx.stroke();ctx.shadowBlur=0;ctx.globalAlpha=1});
  floats.forEach(f=&gt;{ctx.globalAlpha=Math.min(1,f.t);ctx.font=(f.big?'800 20px':'800 14px')+' Courier New';ctx.textAlign='center';ctx.fillStyle='rgba(0,0,0,.7)';ctx.shadowColor=f.col;ctx.shadowBlur=10;ctx.fillText(f.txt,f.x,f.y);ctx.shadowBlur=0;ctx.globalAlpha=1});
  ctx.restore();
}

let last=performance.now();
function loop(t){
  const dt=Math.min((t-last)/1000,.033);last=t;
  if(state==='playing'||state==='clearing'||state==='dying')update(dt);
  else{tSec+=dt;for(let i=parts.length-1;i&gt;=0;i--){const p=parts[i];p.t-=dt;p.x+=(p.vx||0)*dt;p.y+=(p.vy||0)*dt;if(p.t&lt;=0)parts.splice(i,1)}
    for(let i=rings.length-1;i&gt;=0;i--){const r=rings[i];r.r+=r.vr*dt;r.a-=dt*2.2;if(r.a&lt;=0)rings.splice(i,1)}
    for(let i=floats.length-1;i&gt;=0;i--){floats[i].t-=dt;floats[i].y-=28*dt;if(floats[i].t&lt;=0)floats.splice(i,1)}
    shake=Math.max(0,shake-dt*30);recoil=Math.max(0,recoil-dt*24)}
  draw();requestAnimationFrame(loop);
}

addEventListener('keydown',e=&gt;{if(['ArrowUp','ArrowDown','ArrowLeft','ArrowRight','Space'].indexOf(e.code)&gt;=0)e.preventDefault();keys[e.code]=true;if(e.code==='KeyP'||e.code==='Escape')togglePause()});
addEventListener('keyup',e=&gt;{keys[e.code]=false});
addEventListener('blur',()=&gt;{if(state==='playing'||state==='clearing')togglePause(true)});
document.addEventListener('visibilitychange',()=&gt;{if(document.hidden&amp;&amp;(state==='playing'||state==='clearing'))togglePause(true)});
function togglePause(force){
  if(state==='playing'||state==='clearing'){state='paused';$('#pauseOv').classList.add('show');if(musicOn&amp;&amp;musicG){try{musicG.gain.linearRampToValueAtTime(.02,ac().currentTime+.2)}catch(e){}}}
  else if(state==='paused'&amp;&amp;!force){state='playing';$('#pauseOv').classList.remove('show');if(musicOn&amp;&amp;musicG){try{musicG.gain.linearRampToValueAtTime(.07,ac().currentTime+.2)}catch(e){}}}
}
$('#resBtn').addEventListener('click',()=&gt;togglePause());
if('ontouchstart' in window||navigator.maxTouchPoints&gt;0)document.body.classList.add('touch');
let joyOn=false,joyId=null,jcx=0,jcy=0;
const joy=$('#joy'),stick=$('#stick');
$('.screen').addEventListener('pointerdown',function(e){
  if(e.target.closest('#fire')||e.target.closest('.ov')||e.target.closest('.btn')||e.target.closest('.musbtn'))return;
  const st=$('.screen').getBoundingClientRect();const lx=e.clientX-st.left;
  if(lx&lt;st.width*.5){joyOn=true;joyId=e.pointerId;jcx=e.clientX;jcy=e.clientY;
    joy.style.display='block';joy.style.left=(lx-50)+'px';joy.style.top=(e.clientY-st.top-50)+'px';
    stick.style.transform='translate(0,0)';$('.screen').setPointerCapture(e.pointerId)}
});
$('.screen').addEventListener('pointermove',function(e){if(!joyOn||e.pointerId!==joyId)return;const dx=e.clientX-jcx,dy=e.clientY-jcy,d=hyp(dx,dy),m=Math.min(d,42);
  if(d&gt;0){const ddx=dx/d*m,ddy=dy/d*m;stick.style.transform='translate('+ddx+'px,'+ddy+'px)';joyX=ddx/42;joyY=ddy/42}});
$('.screen').addEventListener('pointerup',()=&gt;{joyOn=false;joyX=0;joyY=0;joy.style.display='none'});
$('.screen').addEventListener('pointercancel',()=&gt;{joyOn=false;joyX=0;joyY=0;joy.style.display='none'});
const fb=$('#fire');
fb.addEventListener('pointerdown',e=&gt;{e.preventDefault();firing=true;ac()});
fb.addEventListener('pointerup',()=&gt;{firing=false});
fb.addEventListener('pointercancel',()=&gt;{firing=false});
$('#startBtn').addEventListener('click',()=&gt;{ac();fullReset()});
$('#againBtn').addEventListener('click',()=&gt;{ac();fullReset()});
$('#menuBtn').addEventListener('click',()=&gt;{hideAll();$('#menuOv').classList.add('show');state='menu';genArena();updateComboDisplay();renderTopList();stopMusic()});

/* ИСПРАВЛЕНИЕ: снимаем фокус с кнопок после клика, чтобы Пробел только стрелял */
document.addEventListener('click',e=&gt;{if(e.target&amp;&amp;e.target.blur)e.target.blur()});

genArena();syncHUD();updateComboDisplay();requestAnimationFrame(loop);
})();
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</subtitle>
  <updated>2026-08-14T14:02:42Z</updated>
  <logo>https://pandoraburo.ru/ssl/u/pic/69/be1662953111f1a508b532fbee6d5f/-/logo.png</logo>
  <author>
    <name>1592962</name>
    <uri>https://www.pandoraburo.ru/</uri>
  </author>
</feed>
