TIRE BAR: STREET PATROL

Night run through dystopian Atlanta. Roll out in the service rig, clear the lanes, drop Captain Overtorque at the 750M gate, then face Emperor Torquebane at 1500M. WE HUNT DOWNTIME.

} if (b.spawnsGrunts) { b.gruntT -= dt; if (b.gruntT <= 0) { b.gruntT = 3900; if (G.enemies.filter(e => e.kind === 'foot').length < 2) spawnEnemy(true); } } /* boss body-check */ if (Math.abs((b.x + b.w / 2) - (HERO_X + HERO_W / 2)) < (b.w + HERO_W) / 2 - 20 && Math.abs(b.y - G.heroY) < (b.h + HERO_H) / 2 - 14) { heroHit(20, HERO_X + HERO_W, G.heroY); } } } /* ---------- drawing ---------- */ const STARS = []; for (let i = 0; i < 46; i++) STARS.push({ x: rand(0, W), y: rand(8, 210), r: rand(0.7, 1.9), tw: rand(0, 6) }); function skylineLayer(off, base, hMax, color, seedSkip) { ctx.fillStyle = color; const bw = 46; const start = -((off % bw) + bw) % bw - bw; for (let x = start, i = Math.floor(off / bw) - 1; x < W + bw; x += bw, i++) { const h = 30 + ((Math.sin(i * 12.9898 + seedSkip) * 43758.5453) % 1 + 1) % 1 * hMax; ctx.fillRect(x, base - h, bw - 6, h); if (((i * 7 + seedSkip) % 3) === 0) { /* lit windows */ ctx.fillStyle = 'rgba(255,190,90,0.5)'; ctx.fillRect(x + 8, base - h + 10, 4, 5); ctx.fillRect(x + 24, base - h + 22, 4, 5); ctx.fillStyle = color; } } } function drawBG() { const g = ctx.createLinearGradient(0, 0, 0, H); g.addColorStop(0, '#070912'); g.addColorStop(0.4, '#0b0d14'); g.addColorStop(1, '#100d0a'); ctx.fillStyle = g; ctx.fillRect(0, 0, W, H); /* stars + moon */ STARS.forEach(function (s) { ctx.globalAlpha = 0.45 + 0.4 * Math.sin(G.time / 700 + s.tw); ctx.fillStyle = '#dfe6ff'; ctx.beginPath(); ctx.arc(s.x, s.y, s.r, 0, 7); ctx.fill(); }); ctx.globalAlpha = 1; ctx.fillStyle = '#e8e4d2'; ctx.beginPath(); ctx.arc(408, 64, 21, 0, 7); ctx.fill(); ctx.fillStyle = '#070912'; ctx.beginPath(); ctx.arc(398, 56, 18, 0, 7); ctx.fill(); /* parallax Atlanta skyline */ skylineLayer(G.scroll * 0.12, ROAD_TOP + 6, 120, '#0a0c16', 3); skylineLayer(G.scroll * 0.3, ROAD_TOP + 10, 66, '#05060a', 11); /* streetlight glows sweeping past */ const lampGap = 190; for (let x = -((G.scroll % lampGap) + lampGap) % lampGap; x < W + 60; x += lampGap) { const rg = ctx.createRadialGradient(x, ROAD_TOP + 16, 4, x, ROAD_TOP + 16, 90); rg.addColorStop(0, 'rgba(255,170,80,0.16)'); rg.addColorStop(1, 'rgba(255,170,80,0)'); ctx.fillStyle = rg; ctx.fillRect(x - 90, ROAD_TOP - 60, 180, 160); ctx.fillStyle = '#ffd28a'; ctx.beginPath(); ctx.arc(x, ROAD_TOP + 14, 4, 0, 7); ctx.fill(); } /* asphalt */ ctx.fillStyle = '#141416'; ctx.fillRect(0, ROAD_TOP, W, ROAD_BOT - ROAD_TOP); ctx.fillStyle = '#1d1a12'; ctx.fillRect(0, ROAD_TOP, W, 8); ctx.fillStyle = 'rgba(213,61,34,0.55)'; ctx.fillRect(0, ROAD_TOP + 8, W, 3); ctx.fillStyle = '#1d1a12'; ctx.fillRect(0, ROAD_BOT - 8, W, 8); /* scrolling lane dashes */ ctx.strokeStyle = 'rgba(255,210,138,0.4)'; ctx.lineWidth = 4; ctx.setLineDash([30, 26]); ctx.lineDashOffset = -G.scroll; [(LANES[0] + LANES[1]) / 2, (LANES[1] + LANES[2]) / 2].forEach(function (y) { ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(W, y); ctx.stroke(); }); ctx.setLineDash([]); } function drawWheel(x, y, r, t) { ctx.fillStyle = '#0a0a0c'; ctx.beginPath(); ctx.arc(x, y, r, 0, 7); ctx.fill(); ctx.strokeStyle = '#3c4048'; ctx.lineWidth = 2.5; ctx.stroke(); ctx.strokeStyle = '#8a8f98'; ctx.lineWidth = 2; for (let i = 0; i < 3; i++) { const a = t * 0.012 + i * Math.PI * 2 / 3; ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x + Math.cos(a) * (r - 3), y + Math.sin(a) * (r - 3)); ctx.stroke(); } } function drawHero() { const x = HERO_X, y = G.heroY - HERO_H / 2; const blink = G.heroInv > 0 && Math.floor(G.time / 70) % 2 === 0; ctx.save(); if (blink) ctx.globalAlpha = 0.35; /* service rig body */ ctx.fillStyle = '#181a20'; rr(x, y + 12, HERO_W, HERO_H - 16, 7); ctx.fill(); ctx.fillStyle = '#D53D22'; rr(x, y + 12, HERO_W, 13, 7); ctx.fill(); ctx.fillStyle = '#23252d'; rr(x + 6, y + 30, 52, 20, 4); ctx.fill(); ctx.fillStyle = '#c9ccd4'; ctx.font = '10px Arial Black, Arial'; ctx.textAlign = 'left'; ctx.fillText('FOXXSHOOTER', x + 9, y + 44); /* cab */ ctx.fillStyle = '#20222a'; rr(x + 62, y + 2, 40, 30, 6); ctx.fill(); drawCoverImg(IMG.face, x + 67, y + 6, 22, 22); ctx.strokeStyle = '#FF5E1A'; ctx.lineWidth = 1.5; rr(x + 67, y + 6, 22, 22, 3); ctx.stroke(); ctx.fillStyle = '#ffd28a'; ctx.fillRect(x + 99, y + 26, 4, 6); /* headlight */ const beam = ctx.createLinearGradient(x + 103, 0, x + 175, 0); beam.addColorStop(0, 'rgba(255,210,138,0.20)'); beam.addColorStop(1, 'rgba(255,210,138,0)'); ctx.fillStyle = beam; ctx.beginPath(); ctx.moveTo(x + 103, y + 25); ctx.lineTo(x + 178, y + 12); ctx.lineTo(x + 178, y + 46); ctx.lineTo(x + 103, y + 33); ctx.closePath(); ctx.fill(); drawWheel(x + 24, y + HERO_H - 4, 12, G.time); drawWheel(x + 80, y + HERO_H - 4, 12, G.time); /* bed gear: spare tire + light bar */ ctx.fillStyle = '#0d0d10'; ctx.beginPath(); ctx.ellipse(x + 18, y + 20, 10, 7, 0, 0, 7); ctx.fill(); ctx.strokeStyle = '#3c4048'; ctx.lineWidth = 2; ctx.stroke(); ctx.fillStyle = '#FF5E1A'; ctx.fillRect(x + 60, y - 3, 26, 5); /* muzzle flash */ if (G.muzzle > 0) { ctx.fillStyle = 'rgba(255,225,77,0.9)'; ctx.beginPath(); ctx.moveTo(x + HERO_W + 2, G.heroY - 14); ctx.lineTo(x + HERO_W + 22, G.heroY - 8); ctx.lineTo(x + HERO_W + 2, G.heroY - 2); ctx.closePath(); ctx.fill(); } ctx.restore(); } function drawEnemy(e) { const cx = e.x, cy = e.y + Math.sin(G.time / 260 + e.wob) * 1.5; ctx.save(); if (e.kind === 'foot') { const w = e.w, h = e.h, x = cx - w / 2, y = cy - h / 2; ctx.fillStyle = '#0d0d10'; rr(x - 3, y - 3, w + 6, h + 6, 7); ctx.fill(); drawCoverImg(IMG.grunt, x, y, w, h); ctx.strokeStyle = e.shooter ? '#ffcf3f' : '#D53D22'; ctx.lineWidth = 2; rr(x - 3, y - 3, w + 6, h + 6, 7); ctx.stroke(); ctx.fillStyle = 'rgba(0,0,0,0.55)'; ctx.fillRect(x - 3, y - 18, w + 6, 14); ctx.fillStyle = '#ffb59f'; ctx.font = '8px Arial Black, Arial'; ctx.textAlign = 'center'; ctx.fillText(e.shooter ? 'LEGION GUNNER' : 'TREAD LEGION', cx, y - 8); } else { /* rolling Legion rig */ const w = e.w, h = e.h, x = cx - w / 2, y = cy - h / 2; ctx.fillStyle = '#14151b'; rr(x, y + 8, w, h - 12, 7); ctx.fill(); ctx.fillStyle = '#26262e'; rr(x + 4, y + 14, 56, 26, 4); ctx.fill(); drawCoverImg(IMG.grunt, x + 7, y + 16, 30, 22); ctx.strokeStyle = '#D53D22'; ctx.lineWidth = 1.5; rr(x + 7, y + 16, 30, 22, 3); ctx.stroke(); ctx.fillStyle = '#3a0f0a'; rr(x + 64, y + 2, 40, 30, 6); ctx.fill(); ctx.fillStyle = '#0e1420'; ctx.fillRect(x + 68, y + 6, 24, 16); ctx.fillStyle = '#D53D22'; ctx.fillRect(x, y + 8, 5, 10); drawWheel(x + 26, y + h - 2, 11, -G.time); drawWheel(x + 82, y + h - 2, 11, -G.time); if (e.shooter) { ctx.fillStyle = '#ffcf3f'; ctx.fillRect(x + 44, y - 2, 18, 5); } } if (e.flash > 0) { ctx.fillStyle = 'rgba(255,255,255,' + (e.flash / 100) + ')'; ctx.fillRect(cx - e.w / 2, cy - e.h / 2, e.w, e.h); } ctx.restore(); /* hp pips */ for (let i = 0; i < e.maxHp; i++) { ctx.fillStyle = i < e.hp ? '#FF5E1A' : '#3a3a3a'; ctx.fillRect(cx - e.maxHp * 6 + i * 12, cy + e.h / 2 + 5, 9, 4); } } function drawHazard(hz) { const cx = hz.x, cy = hz.y; ctx.save(); if (hz.kind === 'hole') { ctx.fillStyle = '#060607'; ctx.beginPath(); ctx.ellipse(cx, cy + 8, hz.w / 2, hz.h / 2, 0, 0, 7); ctx.fill(); ctx.strokeStyle = '#33363f'; ctx.lineWidth = 2; ctx.stroke(); ctx.strokeStyle = 'rgba(160,160,170,0.5)'; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.moveTo(cx - hz.w / 2 - 6, cy); ctx.lineTo(cx - 8, cy + 6); ctx.moveTo(cx + 10, cy + 2); ctx.lineTo(cx + hz.w / 2 + 8, cy - 4); ctx.stroke(); } else { for (let r = 0; r < 2; r++) for (let cix = 0; cix < 2; cix++) { const tx = cx - 20 + cix * 26 + (r ? 7 : 0), ty = cy + 12 - r * 17; ctx.fillStyle = '#17181c'; ctx.beginPath(); ctx.ellipse(tx, ty, 16, 10, 0, 0, 7); ctx.fill(); ctx.strokeStyle = '#33363f'; ctx.lineWidth = 2; ctx.stroke(); ctx.fillStyle = '#0a0a0c'; ctx.beginPath(); ctx.ellipse(tx, ty, 7, 4, 0, 0, 7); ctx.fill(); } ctx.fillStyle = 'rgba(0,0,0,0.55)'; ctx.fillRect(cx - 32, cy - 34, 64, 13); ctx.fillStyle = '#ffb59f'; ctx.font = '8px Arial Black, Arial'; ctx.textAlign = 'center'; ctx.fillText('TIRE STACK', cx, cy - 24); } if (hz.flash > 0) { ctx.fillStyle = 'rgba(255,255,255,' + (hz.flash / 100) + ')'; ctx.fillRect(cx - hz.w / 2, cy - hz.h / 2, hz.w, hz.h); } ctx.restore(); } function drawPickup(p) { const bob = Math.sin(G.time / 240 + p.x) * 4; const x = p.x, y = p.y + bob; ctx.save(); const pulse = 0.75 + 0.25 * Math.sin(G.time / 130); ctx.globalAlpha = pulse; ctx.fillStyle = 'rgba(0,0,0,0.6)'; rr(x - 19, y - 19, 38, 38, 9); ctx.fill(); ctx.lineWidth = 2.5; if (p.kind === 'wrench') { ctx.strokeStyle = '#7CFC00'; rr(x - 19, y - 19, 38, 38, 9); ctx.stroke(); ctx.strokeStyle = '#c9ccd4'; ctx.lineWidth = 4.5; ctx.lineCap = 'round'; ctx.beginPath(); ctx.moveTo(x - 8, y + 9); ctx.lineTo(x + 4, y - 3); ctx.stroke(); ctx.beginPath(); ctx.arc(x + 8, y - 7, 6, 0.7, 5.4); ctx.stroke(); } else if (p.kind === 'badge') { ctx.strokeStyle = '#ffe14d'; rr(x - 19, y - 19, 38, 38, 9); ctx.stroke(); ctx.fillStyle = '#ffe14d'; ctx.beginPath(); for (let i = 0; i < 5; i++) { const a = -Math.PI / 2 + i * Math.PI * 4 / 5; const px = x + Math.cos(a) * 11, py = y + Math.sin(a) * 11; if (i === 0) ctx.moveTo(px, py); else ctx.lineTo(px, py); } ctx.closePath(); ctx.fill(); } else { ctx.strokeStyle = '#9be7ff'; rr(x - 19, y - 19, 38, 38, 9); ctx.stroke(); ctx.fillStyle = '#9be7ff'; rr(x - 6, y - 11, 12, 22, 3); ctx.fill(); ctx.fillStyle = '#0a2a3a'; ctx.fillRect(x - 6, y - 4, 12, 3); ctx.fillStyle = '#fff'; ctx.font = '8px Arial Black, Arial'; ctx.textAlign = 'center'; ctx.fillText('FUEL', x, y + 22); } ctx.restore(); } function drawBoss(b) { const x = b.x, y = b.y - b.h / 2; ctx.save(); /* armored rig body */ ctx.fillStyle = '#101116'; rr(x, y + 14, b.w, b.h - 18, 9); ctx.fill(); ctx.fillStyle = b.kind === 'torquebane' ? '#3a0f0a' : '#1c1e26'; rr(x, y + 14, b.w, 20, 9); ctx.fill(); ctx.fillStyle = '#26262e'; rr(x + 10, y + 38, b.w * 0.52, b.h - 52, 5); ctx.fill(); drawCoverImg(IMG[b.img], x + 14, y + 41, b.w * 0.44, b.h - 58); ctx.strokeStyle = '#D53D22'; ctx.lineWidth = 2; rr(x + 14, y + 41, b.w * 0.44, b.h - 58, 4); ctx.stroke(); /* cab + armor plates */ ctx.fillStyle = '#1a1c24'; rr(x + b.w - 62, y + 4, 56, 40, 7); ctx.fill(); ctx.fillStyle = '#0e1420'; ctx.fillRect(x + b.w - 56, y + 9, 34, 20); ctx.fillStyle = '#D53D22'; for (let i = 0; i < 3; i++) ctx.fillRect(x + 16 + i * 26, y + 18, 18, 5); ctx.fillStyle = '#8a8f98'; ctx.fillRect(x + b.w - 8, y + 22, 5, 14); /* exhaust */ drawWheel(x + 34, y + b.h - 2, 15, -G.time); drawWheel(x + b.w - 44, y + b.h - 2, 15, -G.time); if (b.flash > 0) { ctx.fillStyle = 'rgba(255,255,255,' + (b.flash / 100) + ')'; ctx.fillRect(x, y, b.w, b.h); } ctx.restore(); /* name plate */ ctx.fillStyle = 'rgba(0,0,0,0.6)'; ctx.fillRect(x + b.w / 2 - 92, y - 24, 184, 17); ctx.fillStyle = '#ff8a75'; ctx.font = '11px Arial Black, Arial'; ctx.textAlign = 'center'; ctx.fillText(b.name, x + b.w / 2, y - 11); } function drawPartsAndFloaters() { G.parts.forEach(function (p) { ctx.globalAlpha = Math.max(0, 1 - p.t / p.life); ctx.fillStyle = p.color; ctx.beginPath(); ctx.arc(p.x, p.y, p.r, 0, 7); ctx.fill(); }); ctx.globalAlpha = 1; G.floaters.forEach(function (f) { ctx.globalAlpha = Math.max(0, 1 - f.t / f.life); ctx.fillStyle = f.color; ctx.font = f.size + 'px Arial Black, Arial'; ctx.textAlign = 'center'; ctx.strokeStyle = 'rgba(0,0,0,0.7)'; ctx.lineWidth = 3; ctx.strokeText(f.text, f.x, f.y); ctx.fillText(f.text, f.x, f.y); }); ctx.globalAlpha = 1; } const PAUSE_BTN = { x: W - 52, y: 10, w: 42, h: 34 }; const MUTE_BTN = { x: W - 100, y: 10, w: 42, h: 34 }; const FIRE_BTN = { x: 424, y: 700, r: 40 }; function drawHUD() { ctx.fillStyle = 'rgba(0,0,0,0.72)'; ctx.fillRect(0, 0, W, 52); ctx.fillStyle = '#FF5E1A'; ctx.fillRect(0, 52, W, 3); ctx.textAlign = 'left'; ctx.fillStyle = '#fff'; ctx.font = '19px Arial Black, Arial'; ctx.fillText('SCORE ' + G.score, 12, 34); ctx.textAlign = 'center'; ctx.fillStyle = '#ffd28a'; ctx.fillText(Math.floor(G.dist) + 'M', W / 2 - 24, 34); if (G.combo >= 2) { ctx.fillStyle = '#ffe14d'; ctx.font = '13px Arial Black, Arial'; ctx.textAlign = 'left'; ctx.fillText('COMBO x' + comboMult().toFixed(1), 12, 76); } ctx.fillStyle = '#22242c'; rr(PAUSE_BTN.x, PAUSE_BTN.y, PAUSE_BTN.w, PAUSE_BTN.h, 6); ctx.fill(); ctx.fillStyle = '#fff'; ctx.fillRect(PAUSE_BTN.x + 12, PAUSE_BTN.y + 9, 6, 16); ctx.fillRect(PAUSE_BTN.x + 24, PAUSE_BTN.y + 9, 6, 16); ctx.fillStyle = '#22242c'; rr(MUTE_BTN.x, MUTE_BTN.y, MUTE_BTN.w, MUTE_BTN.h, 6); ctx.fill(); ctx.font = '17px Arial'; ctx.textAlign = 'center'; ctx.fillText(muted ? '🔇' : '🔊', MUTE_BTN.x + 21, MUTE_BTN.y + 24); /* hull bar */ ctx.fillStyle = '#cfd2d8'; ctx.font = '12px Arial Black, Arial'; ctx.textAlign = 'left'; ctx.fillText('HULL', 12, 100); ctx.fillStyle = '#2b2b2b'; ctx.fillRect(58, 88, W - 190, 13); ctx.fillStyle = G.hull > 50 ? '#59c135' : (G.hull > 25 ? '#ffb300' : '#D53D22'); ctx.fillRect(58, 88, (W - 190) * clamp(G.hull, 0, 100) / 100, 13); ctx.strokeStyle = '#555'; ctx.lineWidth = 1; ctx.strokeRect(58, 88, W - 190, 13); /* weapon state */ if (G.weapon !== 'gun') { ctx.fillStyle = '#ffe14d'; ctx.font = '12px Arial Black, Arial'; ctx.textAlign = 'right'; ctx.fillText((G.weapon === 'rapid' ? 'RAPID FIRE' : 'SPREAD SHOT') + ' ' + Math.ceil(G.weaponT / 1000) + 's', W - 12, 100); } else if (!G.boss && !G.endless) { ctx.fillStyle = '#9aa0a8'; ctx.font = '12px Arial Black, Arial'; ctx.textAlign = 'right'; const nextGate = G.bossStage === 0 ? BOSS_GATES[0] : BOSS_GATES[1]; ctx.fillText('NEXT GATE ' + Math.max(0, Math.ceil(nextGate - G.dist)) + 'M', W - 12, 100); } else if (G.endless) { ctx.fillStyle = '#9aa0a8'; ctx.font = '12px Arial Black, Arial'; ctx.textAlign = 'right'; ctx.fillText('ENDLESS PATROL', W - 12, 100); } /* boss hp */ if (G.boss) { const b = G.boss; ctx.fillStyle = 'rgba(0,0,0,0.6)'; ctx.fillRect(60, 112, W - 120, 20); ctx.fillStyle = '#ff8a75'; ctx.font = '11px Arial Black, Arial'; ctx.textAlign = 'center'; ctx.fillText(b.name, W / 2, 126); ctx.fillStyle = '#2b2b2b'; ctx.fillRect(60, 136, W - 120, 10); ctx.fillStyle = b.hp <= b.maxHp * 0.25 ? '#D53D22' : '#FF5E1A'; ctx.fillRect(60, 136, (W - 120) * Math.max(0, b.hp) / b.maxHp, 10); ctx.strokeStyle = '#555'; ctx.lineWidth = 1; ctx.strokeRect(60, 136, W - 120, 10); } /* touch pads */ if (G.state === 'play') { ctx.save(); ctx.globalAlpha = G.firing ? 0.5 : 0.28; ctx.fillStyle = '#D53D22'; ctx.beginPath(); ctx.arc(FIRE_BTN.x, FIRE_BTN.y, FIRE_BTN.r, 0, 7); ctx.fill(); ctx.globalAlpha = 0.9; ctx.fillStyle = '#fff'; ctx.font = '15px Arial Black, Arial'; ctx.textAlign = 'center'; ctx.fillText('FIRE', FIRE_BTN.x, FIRE_BTN.y + 5); ctx.restore(); ctx.fillStyle = 'rgba(255,255,255,0.30)'; ctx.font = '20px Arial Black, Arial'; ctx.textAlign = 'left'; ctx.fillText('▲', 18, 686); ctx.fillText('▼', 18, 738); } } function drawBanner() { if (!G.banner) return; const b = G.banner, a = b.t < 150 ? b.t / 150 : (b.t > b.life - 300 ? Math.max(0, (b.life - b.t) / 300) : 1); ctx.save(); ctx.globalAlpha = a; ctx.fillStyle = 'rgba(0,0,0,0.55)'; ctx.fillRect(0, 190, W, 96); ctx.fillStyle = '#FF5E1A'; ctx.fillRect(0, 190, W, 3); ctx.fillRect(0, 283, W, 3); ctx.fillStyle = '#fff'; ctx.font = '30px Arial Black, Arial'; ctx.textAlign = 'center'; ctx.fillText(b.text, W / 2, 232); ctx.fillStyle = '#ffd28a'; ctx.font = '14px Arial Black, Arial'; ctx.fillText(b.sub, W / 2, 260); ctx.restore(); } function bigButton(x, y, w, h, label, color) { ctx.fillStyle = color || '#D53D22'; rr(x, y, w, h, 12); ctx.fill(); ctx.strokeStyle = 'rgba(255,255,255,0.5)'; ctx.lineWidth = 2; rr(x, y, w, h, 12); ctx.stroke(); ctx.fillStyle = '#fff'; ctx.font = '22px Arial Black, Arial'; ctx.textAlign = 'center'; ctx.fillText(label, x + w / 2, y + h / 2 + 8); return { x: x, y: y, w: w, h: h }; } let playBtn = null, againBtn = null, resumeBtn = null, endlessBtn = null; function drawTitle() { ctx.fillStyle = 'rgba(0,0,0,0.45)'; ctx.fillRect(0, 0, W, H); drawFitImg(IMG.hero, 100, 84, 280, 280); ctx.strokeStyle = '#FF5E1A'; ctx.lineWidth = 3; rr(100, 84, 280, 280, 10); ctx.stroke(); ctx.textAlign = 'center'; ctx.fillStyle = '#FF5E1A'; ctx.font = '40px Arial Black, Arial'; ctx.fillText('TIRE BAR', W / 2, 424); ctx.fillStyle = '#fff'; ctx.font = '31px Arial Black, Arial'; ctx.fillText('STREET PATROL', W / 2, 462); ctx.fillStyle = '#ffd28a'; ctx.font = '16px Arial Black, Arial'; ctx.fillText('"WE HUNT DOWNTIME"', W / 2, 494); ctx.fillStyle = '#cfd2d8'; ctx.font = '14px Arial, sans-serif'; ctx.fillText('Roll the Atlanta streets. LEFT side steers lanes,', W / 2, 534); ctx.fillText('hold the RIGHT side (or FIRE) to shoot.', W / 2, 556); ctx.fillText('Dodge bolts, potholes and tire stacks — or blast', W / 2, 578); ctx.fillText('them clear. Grab wrenches, badges and fuel.', W / 2, 600); ctx.fillText('750M: Captain Overtorque. 1500M: Emperor Torquebane.', W / 2, 630); playBtn = bigButton(W / 2 - 110, 664, 220, 62, '▶ PLAY'); } function drawEndScreen(win) { ctx.fillStyle = 'rgba(0,0,0,0.78)'; ctx.fillRect(0, 0, W, H); ctx.textAlign = 'center'; if (win) { drawFitImg(IMG.hero, 140, 104, 200, 200); ctx.strokeStyle = '#FF5E1A'; ctx.lineWidth = 3; rr(140, 104, 200, 200, 10); ctx.stroke(); ctx.fillStyle = '#7CFC00'; ctx.font = '34px Arial Black, Arial'; ctx.fillText('STREETS CLEAR!', W / 2, 356); ctx.fillStyle = '#fff'; ctx.font = '18px Arial Black, Arial'; ctx.fillText('EMPEROR TORQUEBANE IS DOWN', W / 2, 388); } else { drawCoverImg(IMG.torquebaneFull, 140, 104, 200, 200); ctx.strokeStyle = '#D53D22'; ctx.lineWidth = 3; rr(140, 104, 200, 200, 10); ctx.stroke(); ctx.fillStyle = '#D53D22'; ctx.font = '36px Arial Black, Arial'; ctx.fillText('RIG WRECKED', W / 2, 356); ctx.fillStyle = '#fff'; ctx.font = '18px Arial Black, Arial'; ctx.fillText('THE LEGION OWNS THESE STREETS... TONIGHT', W / 2, 388); ctx.fillStyle = '#cfd2d8'; ctx.font = '15px Arial, sans-serif'; ctx.fillText('Made it ' + G.finalDist + 'M', W / 2, 414); } ctx.fillStyle = '#ffd28a'; ctx.font = '26px Arial Black, Arial'; ctx.fillText('SCORE ' + G.score, W / 2, 468); ctx.fillStyle = '#9aa0a8'; ctx.font = '15px Arial Black, Arial'; ctx.fillText('LEGION DOWN: ' + G