🎮ArcadeLab

Spanish MultiGame - 5 режимов | Защита 100x

by HyperScout89
324 lines23.7 KB
▶ Play
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover">
  <title>Spanish MultiGame - 5 режимов | Защита 100x</title>
  <style>
    * {
      user-select: none;
      -webkit-tap-highlight-color: transparent;
      box-sizing: border-box;
    }
    body {
      background: radial-gradient(circle at 20% 30%, #0a1f2c, #030c12);
      min-height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
      font-family: system-ui, 'Segoe UI', sans-serif;
      margin: 0;
      padding: 16px;
    }
    .master-container {
      width: 100%;
      max-width: 1300px;
      background: rgba(0,0,0,0.5);
      border-radius: 64px;
      backdrop-filter: blur(12px);
      padding: 20px;
      box-shadow: 0 30px 50px rgba(0,0,0,0.6);
    }
    .menu-bar {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      gap: 14px;
      margin-bottom: 24px;
      background: #1e2f2ad9;
      padding: 12px 20px;
      border-radius: 80px;
    }
    .mode-btn {
      background: #2c4a3e;
      border: none;
      color: #ffefcf;
      font-weight: bold;
      padding: 8px 20px;
      border-radius: 60px;
      cursor: pointer;
      transition: 0.1s;
      font-size: 0.9rem;
      box-shadow: 0 2px 6px black;
    }
    .mode-btn.active {
      background: #ff914d;
      color: #1f2a0e;
      box-shadow: 0 0 0 2px gold;
    }
    .game-panel {
      background: #00000066;
      border-radius: 48px;
      padding: 16px;
    }
    canvas {
      display: block;
      margin: 0 auto;
      border-radius: 32px;
      background: #fffaf0;
      width: 100%;
      height: auto;
      touch-action: none;
      cursor: pointer;
    }
    .info-area {
      display: flex;
      justify-content: space-between;
      align-items: center;
      flex-wrap: wrap;
      gap: 12px;
      margin-top: 16px;
      margin-bottom: 12px;
      background: #00000099;
      padding: 8px 20px;
      border-radius: 60px;
      color: #f9eec1;
    }
    .stat {
      background: #0f281cd9;
      padding: 4px 16px;
      border-radius: 50px;
      font-weight: bold;
      font-family: monospace;
    }
    button {
      background: linear-gradient(145deg, #ffa25b, #ff7b2c);
      border: none;
      font-weight: bold;
      padding: 6px 20px;
      border-radius: 60px;
      cursor: pointer;
      box-shadow: 0 3px 0 0 #8b3a0a;
    }
    button:active { transform: translateY(2px); box-shadow: 0 1px 0 0 #8b3a0a; }
    .lang-select {
      background: #0a1a12;
      padding: 6px 14px;
      border-radius: 40px;
      color: #ffefb9;
      font-weight: bold;
      border: 1px solid #ffb458;
    }
    @media (max-width: 700px) { .mode-btn { padding: 5px 12px; font-size: 0.7rem; } .stat { font-size: 0.8rem; } }
  </style>
</head>
<body>
<div class="master-container">
  <div class="menu-bar">
    <button class="mode-btn" data-mode="standard">📖 СТАНДАРТ</button>
    <button class="mode-btn" data-mode="blockblast">🧩 ТЕТРИС (Block Blast)</button>
    <button class="mode-btn" data-mode="race">👾 ИНОПЛАНЕТНАЯ ГОНКА (бот)</button>
    <button class="mode-btn" data-mode="raceonline">🌐 ГОНКА ONLINE (код)</button>
    <button class="mode-btn" data-mode="transport">🚋 ТРАНСПОРТ (маршрут)</button>
  </div>
  <div class="game-panel">
    <div class="info-area">
      <div class="stat">🎯 SCORE: <span id="globalScore">0</span></div>
      <div class="stat">🪙 <span id="globalCoins">30</span></div>
      <div id="modeSpecificStat" class="stat">⚡ Режим: Стандарт</div>
      <select id="langSwitcher" class="lang-select">
        <option value="ru">🇷🇺 Русский</option>
        <option value="en">🇬🇧 English</option>
      </select>
      <button id="resetModeBtn">🔄 Сброс режима</button>
    </div>
    <canvas id="gameCanvas" width="1000" height="520" style="width:100%; aspect-ratio:1000/520"></canvas>
    <div id="feedbackMsg" style="background:#000000aa; border-radius:60px; padding:8px; margin-top:12px; text-align:center; font-weight:bold;">✨ Выберите режим ✨</div>
  </div>
</div>

<script>
  (function(){
    // ======================== ГЛОБАЛЬНАЯ ЗАЩИТА 100x ========================
    let currentMode = "standard";     // standard, blockblast, race, raceonline, transport
    let globalScore = 0;
    let globalCoins = 30;
    let currentLang = "ru";
    let gameActive = true;
    let animationFrame = null;
    let canvas = document.getElementById('gameCanvas');
    let ctx = canvas.getContext('2d');
    
    // ---- Словарь слов (исп-англ) ----
    const WORD_SET = [
      { spanish: "Hola", english: "hello" },{ spanish: "Amigo", english: "friend" },{ spanish: "Uno", english: "one" },
      { spanish: "Dos", english: "two" },{ spanish: "Tres", english: "three" },{ spanish: "Cuatro", english: "four" },
      { spanish: "Cinco", english: "five" },{ spanish: "Adiós", english: "bye" },{ spanish: "Gracias", english: "thanks" },
      { spanish: "Rojo", english: "red" },{ spanish: "Azul", english: "blue" },{ spanish: "Verde", english: "green" },
      { spanish: "Perro", english: "dog" },{ spanish: "Gato", english: "cat" },{ spanish: "Casa", english: "house" },
      { spanish: "Feliz", english: "happy" },{ spanish: "Triste", english: "sad" },{ spanish: "Rápido", english: "fast" },
      { spanish: "Grande", english: "big" }
    ];
    
    // Переводы UI
    const langUI = {
      ru: { standard:"Стандарт: лови правильное слово", block:"Block Blast: заполняй линии", race:"Гонка: бей метеориты", raceOnline:"Гонка онлайн (код)", transport:"Транспорт: впускай пассажиров", correct:"Верно!", wrong:"Ошибка", lineClear:"Линия очищена", meteorHit:"Метеорит сбит", passengerOk:"Пассажир зашёл", passengerBad:"Не впускай!", gameOver:"ИГРА ЗАВЕРШЕНА" },
      en: { standard:"Standard: catch falling word", block:"Block Blast: fill lines", race:"Race: hit meteorites", raceOnline:"Online race (code)", transport:"Transport: let passengers in", correct:"Correct!", wrong:"Wrong", lineClear:"Line cleared", meteorHit:"Meteor hit", passengerOk:"Passenger entered", passengerBad:"Do not let!", gameOver:"GAME OVER" }
    };
    function tr(key) { return langUI[currentLang][key] || key; }
    
    // Обновление интерфейса
    function updateGlobalUI() {
      document.getElementById('globalScore').innerText = globalScore;
      document.getElementById('globalCoins').innerText = globalCoins;
    }
    function addCoins(amount) { globalCoins += amount; updateGlobalUI(); }
    function spendCoins(amount) { if(globalCoins>=amount) { globalCoins-=amount; updateGlobalUI(); return true; } return false; }
    function addScore(amount) { globalScore += amount; updateGlobalUI(); }
    
    // ======================== РЕЖИМ 1: СТАНДАРТ (падение слов) ========================
    let stdState = { activeWords: [], spawnInterval: null, timerInterval: null, timeLeft: 60, targetWord: "hello", clickLock: false };
    function spawnStandardWord() {
      if(!gameActive || currentMode!=='standard') return;
      let random = WORD_SET[Math.floor(Math.random()*WORD_SET.length)];
      let isMatch = (random.english === stdState.targetWord);
      let speed = 2.2 + Math.random()*1.2;
      let textWidth = ctx.measureText(random.spanish).width + 30;
      let x = Math.max(10, Math.random()*(canvas.width - textWidth - 20));
      stdState.activeWords.push({ text: random.spanish, x, y: -30, speed, isMatch, width: textWidth });
    }
    function drawStandard() {
      ctx.clearRect(0,0,canvas.width,canvas.height);
      for(let w of stdState.activeWords) {
        ctx.shadowBlur=4; ctx.beginPath(); ctx.roundRect(w.x-8,w.y-6,w.width+16,46,20);
        ctx.fillStyle = w.isMatch?"#ffe0b0dd":"#fcf5e6dd"; ctx.fill();
        ctx.font="bold 26px system-ui"; ctx.fillStyle = w.isMatch?"#bc4518":"#2a6825";
        ctx.fillText(w.text, w.x, w.y+28);
        if(w.isMatch){ ctx.fillStyle="#e07c2c"; ctx.fillText(w.text, w.x-1, w.y+27); }
      }
      if(!gameActive){ ctx.globalAlpha=0.8; ctx.fillStyle="#0f1b12e6"; ctx.fillRect(0,0,canvas.width,canvas.height); ctx.globalAlpha=1; ctx.fillStyle="white"; ctx.font="bold 30px"; ctx.fillText(tr('gameOver'),canvas.width/2-100,canvas.height/2); }
    }
    function updateStandard() {
      if(!gameActive) return;
      for(let i=0;i<stdState.activeWords.length;i++){ stdState.activeWords[i].y += stdState.activeWords[i].speed; if(stdState.activeWords[i].y>canvas.height+80) stdState.activeWords.splice(i,1),i--; }
    }
    function handleStandardTap(e) {
      if(!gameActive || currentMode!=='standard' || stdState.clickLock) return;
      stdState.clickLock=true; setTimeout(()=>stdState.clickLock=false,120);
      let {x,y}=getCanvasCoords(e); if(x===null) return;
      for(let i=stdState.activeWords.length-1;i>=0;i--){
        let w=stdState.activeWords[i];
        if(x>w.x-15 && x<w.x+w.width+15 && y>w.y-15 && y<w.y+50){
          if(w.isMatch){ addScore(10); addCoins(1); showFeed(tr('correct'),true); stdState.activeWords.splice(i,1); changeTargetStandard(); restartStdSpawn(); }
          else { addScore(-5); showFeed(tr('wrong'),false); stdState.activeWords.splice(i,1); restartStdSpawn(); }
          break;
        }
      }
    }
    function changeTargetStandard(){ let newT; do{ newT=WORD_SET[Math.floor(Math.random()*WORD_SET.length)].english; }while(newT===stdState.targetWord); stdState.targetWord=newT; document.getElementById('modeSpecificStat').innerHTML=`🎯 ${stdState.targetWord}`; }
    function restartStdSpawn(){ if(stdState.spawnInterval)clearInterval(stdState.spawnInterval); stdState.spawnInterval=setInterval(()=>{ if(currentMode==='standard' && gameActive) spawnStandardWord(); },1300); }
    function startStandardTimer(){ if(stdState.timerInterval)clearInterval(stdState.timerInterval); stdState.timerInterval=setInterval(()=>{ if(currentMode!=='standard' || !gameActive) return; stdState.timeLeft--; if(stdState.timeLeft<=0) terminateGame(); document.getElementById('modeSpecificStat').innerHTML=`⏱️ ${stdState.timeLeft}s  🎯 ${stdState.targetWord}`; },1000); }
    
    // ======================== РЕЖИМ 2: BLOCK BLAST (тетрис-матчинг) ========================
    let blastGrid = Array(8).fill().map(()=>Array(8).fill(0));
    let currentBlock = { shape: [[1,1],[1,1]], w:2, h:2 }; // случайный блок
    function generateRandomBlock(){ let type=Math.floor(Math.random()*3); if(type===0) currentBlock={shape:[[1,1,1]], w:3,h:1}; else if(type===1) currentBlock={shape:[[1],[1],[1]], w:1,h:3}; else currentBlock={shape:[[1,1],[1,1]], w:2,h:2}; }
    function drawBlast(){
      ctx.clearRect(0,0,canvas.width,canvas.height); let cellW=canvas.width/8, cellH=canvas.height/8;
      for(let i=0;i<8;i++) for(let j=0;j<8;j++){ if(blastGrid[i][j]){ ctx.fillStyle="#8bc34a"; ctx.fillRect(j*cellW,i*cellH,cellW-2,cellH-2); } else { ctx.strokeStyle="#ccc"; ctx.strokeRect(j*cellW,i*cellH,cellW-2,cellH-2); } }
      // отрисовка текущего блока
      ctx.fillStyle="#ffaa44"; for(let i=0;i<currentBlock.h;i++) for(let j=0;j<currentBlock.w;j++) if(currentBlock.shape[i]?.[j]) ctx.fillRect( (4+j)*cellW, (0+i)*cellH, cellW-2, cellH-2);
      ctx.fillStyle="white"; ctx.font="18px"; ctx.fillText("Кликни на сетку, чтобы разместить блок",10,40);
    }
    function checkLinesAndClear(){ let cleared=false; for(let i=0;i<8;i++){ let fullRow=true; for(let j=0;j<8;j++) if(!blastGrid[i][j]) fullRow=false; if(fullRow){ for(let k=0;k<8;k++) blastGrid[i][k]=0; addScore(20); addCoins(2); cleared=true; } }
      for(let j=0;j<8;j++){ let fullCol=true; for(let i=0;i<8;i++) if(!blastGrid[i][j]) fullCol=false; if(fullCol){ for(let i=0;i<8;i++) blastGrid[i][j]=0; addScore(20); addCoins(2); cleared=true; } }
      if(cleared) showFeed(tr('lineClear'),true);
    }
    function handleBlastTap(e){
      let {x,y}=getCanvasCoords(e); if(x===null) return; let cellW=canvas.width/8, cellH=canvas.height/8; let col=Math.floor(x/cellW), row=Math.floor(y/cellH);
      if(row>=0 && row<8 && col>=0 && col<8 && row+currentBlock.h<=8 && col+currentBlock.w<=8){
        let canPlace=true; for(let i=0;i<currentBlock.h;i++) for(let j=0;j<currentBlock.w;j++) if(currentBlock.shape[i]?.[j] && blastGrid[row+i][col+j]) canPlace=false;
        if(canPlace){ for(let i=0;i<currentBlock.h;i++) for(let j=0;j<currentBlock.w;j++) if(currentBlock.shape[i]?.[j]) blastGrid[row+i][col+j]=1; generateRandomBlock(); checkLinesAndClear(); }
        else showFeed("❌ Место занято",false);
      }
    }
    
    // ======================== РЕЖИМ 3: ИНОПЛАНЕТНАЯ ГОНКА (бот) ========================
    let raceState = { meteorites: [], targetWord: "hello", timeLeft: 30, botScore: 0, playerScore: 0, gameActiveRace: false };
    function spawnMeteor(){ if(!raceState.gameActiveRace) return; let wordObj=WORD_SET[Math.floor(Math.random()*WORD_SET.length)]; let isMatch=(wordObj.english===raceState.targetWord); raceState.meteorites.push({ text:wordObj.spanish, x:Math.random()*(canvas.width-80), y:-40, speed:2+Math.random()*2, isMatch, w:80 }); }
    function drawRace(){ ctx.clearRect(0,0,canvas.width,canvas.height); for(let m of raceState.meteorites){ ctx.fillStyle=m.isMatch?"#ff8866":"#aa99cc"; ctx.beginPath(); ctx.ellipse(m.x+40,m.y+20,40,25,0,0,Math.PI*2); ctx.fill(); ctx.fillStyle="white"; ctx.font="bold 20px"; ctx.fillText(m.text,m.x+15,m.y+25); } ctx.fillStyle="white"; ctx.fillText(`Игрок: ${raceState.playerScore}  Бот: ${raceState.botScore}`,20,40); ctx.fillText(`Цель: ${raceState.targetWord}`,20,80); if(!raceState.gameActiveRace){ ctx.fillStyle="black"; ctx.fillRect(0,0,canvas.width,canvas.height); ctx.fillStyle="white"; ctx.fillText("ГОНКА ЗАВЕРШЕНА",canvas.width/2-100,canvas.height/2); } }
    function updateRace(){ if(!raceState.gameActiveRace) return; for(let i=0;i<raceState.meteorites.length;i++){ raceState.meteorites[i].y+=raceState.meteorites[i].speed; if(raceState.meteorites[i].y>canvas.height) raceState.meteorites.splice(i,1),i--; } if(Math.random()<0.02) spawnMeteor(); }
    function handleRaceTap(e){ if(!raceState.gameActiveRace) return; let {x,y}=getCanvasCoords(e); if(x===null) return; for(let i=0;i<raceState.meteorites.length;i++){ let m=raceState.meteorites[i]; if(x>m.x && x<m.x+80 && y>m.y && y<m.y+45){ if(m.isMatch){ raceState.playerScore+=10; addScore(10); addCoins(1); showFeed(tr('meteorHit'),true); }else{ raceState.playerScore=Math.max(0,raceState.playerScore-5); addScore(-5); } raceState.meteorites.splice(i,1); break; } } }
    function botMoveInRace(){ if(!raceState.gameActiveRace) return; let found=false; for(let m of raceState.meteorites){ if(m.isMatch){ raceState.botScore+=10; found=true; break; } } if(!found && raceState.meteorites.length>0) raceState.botScore=Math.max(0,raceState.botScore-2); }
    function startRaceGame(){ raceState={ meteorites:[], targetWord:WORD_SET[Math.floor(Math.random()*WORD_SET.length)].english, timeLeft:30, botScore:0, playerScore:0, gameActiveRace:true }; let interval=setInterval(()=>{ if(raceState.gameActiveRace){ botMoveInRace(); if(raceState.playerScore>=100 || raceState.botScore>=100 || raceState.timeLeft<=0) { raceState.gameActiveRace=false; clearInterval(interval); showFeed(tr('gameOver'),false); } raceState.timeLeft--; document.getElementById('modeSpecificStat').innerHTML=`🤖 Бот ${raceState.botScore} | 👤 ${raceState.playerScore} | ⏱️ ${raceState.timeLeft}s`; } },1000); }
    
    // ======================== РЕЖИМ 4: ГОНКА ONLINE (код-симуляция) ========================
    let onlineState = { roomCode: null, joined: false, playerScore:0, oppScore:0 };
    function drawOnline(){ ctx.clearRect(0,0,canvas.width,canvas.height); ctx.fillStyle="white"; ctx.fillText("ГОНКА ПО КОДУ",200,100); if(!onlineState.joined){ ctx.fillText("Введите код:",200,150); }else{ ctx.fillText(`Код комнаты: ${onlineState.roomCode}`,200,150); ctx.fillText(`Вы: ${onlineState.playerScore}  Оппонент: ${onlineState.oppScore}`,200,200); } }
    function handleOnlineTap(e){ if(!onlineState.joined){ let code=prompt("Введите код комнаты (1234)"); if(code){ onlineState.roomCode=code; onlineState.joined=true; setInterval(()=>{ onlineState.oppScore+=Math.floor(Math.random()*3); document.getElementById('modeSpecificStat').innerHTML=`Код: ${onlineState.roomCode} | Ваш счёт: ${onlineState.playerScore}`; },1500); } } else { onlineState.playerScore+=10; addScore(10); showFeed("+10",true); } }
    
    // ======================== РЕЖИМ 5: ТРАНСПОРТ (пассажиры) ========================
    let transportState = { passengers:[], currentStation:0, route:["Pl. España","Metro De Hajaul","Calle Barcelona","Pl. Siglo XV","Derzhava"], targetWord:"", scoreTransport:0 };
    function generatePassenger(){ let wordObj=WORD_SET[Math.floor(Math.random()*WORD_SET.length)]; let needMatch=(wordObj.english===transportState.targetWord); transportState.passengers.push({ text:wordObj.spanish, need:needMatch, x:100+Math.random()*300, y:300, w:80 }); }
    function drawTransport(){ ctx.clearRect(0,0,canvas.width,canvas.height); ctx.fillStyle="#c9e2d5"; ctx.fillRect(0,0,canvas.width,canvas.height); ctx.fillStyle="brown"; ctx.fillRect(0,400,canvas.width,80); for(let p of transportState.passengers){ ctx.fillStyle=p.need?"lightgreen":"pink"; ctx.beginPath(); ctx.ellipse(p.x,p.y,30,35,0,0,Math.PI*2); ctx.fill(); ctx.fillStyle="black"; ctx.fillText(p.text,p.x-15,p.y-5); } ctx.fillStyle="white"; ctx.fillText(`Станция: ${transportState.route[transportState.currentStation]} | Цель: ${transportState.targetWord}`,20,50); ctx.fillText(`Очки транспорта: ${transportState.scoreTransport}`,20,90); }
    function handleTransportTap(e){ let {x,y}=getCanvasCoords(e); if(x===null) return; for(let i=0;i<transportState.passengers.length;i++){ let p=transportState.passengers[i]; if(x>p.x-35 && x<p.x+35 && y>p.y-35 && y<p.y+35){ if(p.need){ transportState.scoreTransport+=25; addScore(25); addCoins(2); showFeed(tr('passengerOk'),true); } else { transportState.scoreTransport=Math.max(0,transportState.scoreTransport-20); addScore(-20); showFeed(tr('passengerBad'),false); } transportState.passengers.splice(i,1); break; } } }
    function nextStationTransport(){ transportState.currentStation++; if(transportState.currentStation>=transportState.route.length){ if(confirm("Кольцевой маршрут завершён! Проехать ещё раз?")) transportState.currentStation=0; else terminateGame(); } transportState.targetWord=WORD_SET[Math.floor(Math.random()*WORD_SET.length)].english; for(let i=0;i<2+Math.floor(Math.random()*3);i++) generatePassenger(); document.getElementById('modeSpecificStat').innerHTML=`🚃 ${transportState.route[transportState.currentStation]} | Цель: ${transportState.targetWord}`; }
    function startTransport(){ transportState={ passengers:[], currentStation:0, route:["Pl. España","Metro De Hajaul","Calle Barcelona","Pl. Siglo XV","Derzhava"], targetWord:WORD_SET[0].english, scoreTransport:0 }; for(let i=0;i<3;i++) generatePassenger(); document.getElementById('modeSpecificStat').innerHTML=`🚃 ${transportState.route[0]} | Цель: ${transportState.targetWord}`; setInterval(()=>{ if(currentMode==='transport' && gameActive) nextStationTransport(); },15000); }
    
    // ======================== ОБЩИЕ УТИЛИТЫ ========================
    function getCanvasCoords(e){
      let rect=canvas.getBoundingClientRect(); if(!rect) return {x:null,y:null};
      let cx,cy; if(e.touches){ cx=e.touches[0].clientX; cy=e.touches[0].clientY; e.preventDefault(); } else { cx=e.clientX; cy=e.clientY; }
      let scaleX=canvas.width/rect.width, scaleY=canvas.height/rect.height;
      return { x:(cx-rect.left)*scaleX, y:(cy-rect.top)*scaleY };
    }
    function showFeed(msg,good){ let div=document.getElementById('feedbackMsg'); div.innerHTML=msg; div.style.color=good?"#d0ffb0":"#ffb4a0"; setTimeout(()=>{ if(div.innerHTML===msg) div.innerHTML="✨ "+tr(currentMode)+" ✨"; },1300); }
    function terminateGame(){ gameActive=false; if(animationFrame) cancelAnimationFrame(animationFrame); showFeed(tr('gameOver'),false); }
    function resetMode(){
      gameActive=true;
      if(stdState.spawnInterval) clearInterval(stdState.spawnInterval); if(stdState.timerInterval) clearInterval(stdState.timerInterval);
      if(currentMode==='standard'){ stdState.activeWords=[]; stdState.timeLeft=60; changeTargetStandard(); restartStdSpawn(); startStandardTimer(); }
      if(currentMode==='blockblast'){ blastGrid=Array(8).fill().map(()=>Array(8).fill(0)); generateRandomBlock(); }
      if(currentMode==='race'){ startRaceGame(); }
      if(currentMode==='raceonline'){ onlineState={roomCode:null,joined:false,playerScore:0,oppScore:0}; }
      if(currentMode==='transport'){ startTransport(); }
      document.getElementById('modeSpecificStat').innerHTML=tr(currentMode);
    }
    
    function setMode(mode){
      currentMode=mode; gameActive=true;
      if(stdState.spawnInterval) clearInterval(stdState.spawnInterval); if(stdState.timerInterval) clearInterval(stdState.timerInterval);
      if(animationFrame) cancelAnimationFrame(animationFrame);
      if(mode==='standard'){ stdState={ activeWords:[], spawnInterval:null, timerInterval:null, timeLeft:60, targetWord:"hello", clickLock:false }; changeTargetStandard(); restartStdSpawn(); startStandardTimer(); }
      if(mode==='blockblast'){ blastGrid=Array(8).fill().map(()=>Array(8).fill(0)); generateRandomBlock(); }
      if(mode==='race'){ startRaceGame(); }
      if(mode==='raceonline'){ onlineState={roomCode:null,joined:false,playerScore:0,oppScore:0}; }
      if(mode==='transport'){ startTransport(); }
      document.getElementById('modeSpecificStat').innerHTML=tr(mode);
      function animate(){
        if(!gameActive) return;
        if(currentMode==='standard'){ updateStandard(); drawStandard(); }
        else if(currentMode==='blockblast') drawBlast();
        else if(currentMode==='race'){ updateRace(); drawRace(); }
        else if(currentMode==='raceonline') drawOnline();
        else if(currentMode==='transport') drawTransport();
        animationFrame=requestAnimationFrame(animate);
      }
      animate();
    }
    
    // Привязка событий
    function attachEvents(){
      canvas.addEventListener('click',(e)=>{ e.preventDefault(); if(currentMode==='standard') handleStandardTap(e); else if(currentMode==='blockblast') handleBlastTap(e); else if(currentMode==='race') handleRaceTap(e); else if(currentMode==='raceonline') handleOnlineTap(e); else if(currentMode==='transport') handleTransportTap(e); });
      canvas.addEventListener('touchstart',(e)=>{ e.preventDefault(); let fake={touches:[{clientX:e.touches[0].clientX,clientY:e.touches[0].clientY}], preventDefault:()=>{}}; if(currentMode==='standard') handleStandardTap(fake); else if(currentMode==='blockblast') handleBlastTap(fake); else if(currentMode==='race') handleRaceTap(fake); else if(currentMode==='raceonline') handleOnlineTap(fake); else if(currentMode==='transport') handleTransportTap(fake); });
      document.querySelectorAll('.mode-btn').forEach(btn=>btn.addEventListener('click',()=>setMode(btn.dataset.mode)));
      document.getElementById('resetModeBtn').addEventListener('click',()=>resetMode());
      document.getElementById('langSwitcher').addEventListener('change',(e)=>{ currentLang=e.target.value; updateGlobalUI(); showFeed("Язык изменён",true); });
    }
    updateGlobalUI();
    attachEvents();
    setMode('standard');
  })();
</script>
</body>
</html>

Game Source: Spanish MultiGame - 5 режимов | Защита 100x

Creator: HyperScout89

Libraries: none

Complexity: complex (324 lines, 23.7 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: spanish-multigame-5-100x-hyperscout89" to link back to the original. Then publish at arcadelab.ai/publish.