🎮ArcadeLab

Galaksi Penyamaran - Bab 3

by DriftGlider72
359 lines13.9 KB
▶ Play
<!DOCTYPE html>
<html lang="ms">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Galaksi Penyamaran - Bab 3</title>
    <style>
        * { margin:0; padding:0; box-sizing:border-box; font-family:Arial, sans-serif; touch-action: none; }
        body { 
            background: linear-gradient(180deg, #000022 0%, #220044 100%); 
            color:white; text-align:center; overflow:hidden; 
            height: 100vh; display: flex; flex-direction: column;
        }
        
        #skrinSoalan { 
            font-size: 18px; background:rgba(34, 68, 136, 0.8); 
            padding: 10px; margin: 5px auto; border-radius:8px; 
            width: 95%; border:2px solid #6699ff; font-weight:bold;
        }
        #status { 
            font-size: 18px; display:flex; justify-content:space-around; 
            margin: 5px auto; width: 90%; font-weight:bold;
        }
        #kawasanPermainan { 
            position:relative; width: 100%; flex-grow: 1;
            border-top:2px solid #555; overflow:hidden;
            background: radial-gradient(circle at top, #1a0033 0%, #000011 100%);
        }

        #kapal {
            position:absolute; bottom: 80px; left:50%; transform:translateX(-50%);
            width: 60px; height: 80px; font-size: 45px;
            transition:left 0.05s linear; filter:drop-shadow(0 0 8px #00ccff);
            z-index: 10;
        }

        .peluru {
            position:absolute; width: 8px; height: 22px; 
            background: linear-gradient(to top, #00ffff, #ffffff);
            border-radius:50%; box-shadow:0 0 10px #00ffff, 0 0 20px #00ffff;
            z-index: 15;
            pointer-events: none;
        }
        .kesan-letupan {
            position:absolute; width: 70px; height: 70px;
            background:radial-gradient(circle, #ffff00 0%, #ff6600 50%, transparent 70%);
            border-radius:50%; opacity:0; transform:scale(0);
            animation: meletup 0.4s forwards;
            z-index: 20;
            pointer-events: none;
        }
        @keyframes meletup {
            0% { transform:scale(0); opacity:1; }
            100% { transform:scale(2); opacity:0; }
        }

        .watak {
            position:absolute; width: 70px; height: 90px;
            font-size: 35px;
            display:flex; flex-direction:column; align-items:center;
            z-index: 5;
        }
        .kotak-jawapan {
            background:rgba(255,255,255,0.95); color:black;
            font-size: 17px; font-weight:bold; padding: 4px 6px;
            border-radius:5px; margin-bottom: 2px; min-width: 45px;
        }

        #sinarHijau {
            position:absolute; top:0; left:50%; transform:translateX(-50%);
            width: 10px; height: 100%; background:lime; opacity:0;
            box-shadow:0 0 20px lime, 0 0 40px lime;
            transition:opacity 0.4s; z-index:25;
        }
        #mesejTamat {
            position:absolute; top:50%; left:50%; transform:translate(-50%, -50%);
            font-size: 28px; font-weight:bold; display:none;
            background:rgba(0,0,0,0.9); padding: 25px 30px;
            border-radius:12px; border:3px solid white; z-index:30;
        }
        #butangMulaSemula {
            margin-top: 15px;
            padding: 10px 20px;
            font-size: 18px;
            font-weight: bold;
            background: #28a745;
            color: white;
            border: none;
            border-radius: 8px;
            cursor: pointer;
        }
        #butangMulaSemula:hover {
            background: #218838;
        }
        .bintang {
            position:absolute; background:white; border-radius:50%;
            animation:kelip 2s infinite; pointer-events: none;
        }
        @keyframes kelip { 0%,100% {opacity:0.3;} 50% {opacity:1;} }

        #kawalan {
            display: flex; justify-content: space-between; align-items: center;
            padding: 10px 20px; height: 80px; background: rgba(0,0,0,0.4);
        }
        .btn-kiriKanan, .btn-tembak {
            width: 70px; height: 60px; font-size: 25px; font-weight: bold;
            border: none; border-radius: 10px; background: rgba(102, 153, 255, 0.6);
            color: white; cursor: pointer; user-select: none;
        }
        .btn-kiriKanan:active, .btn-tembak:active { background: rgba(102, 153, 255, 0.9); transform: scale(0.95); }
        .kumpul-kiriKanan { display: flex; gap: 10px; }
    </style>
</head>
<body>

<div id="skrinSoalan">Soalan akan muncul di sini</div>
<div id="status">
    <div>🎯 Mata: <span id="nilaiMata">0</span>/100</div>
    <div>❤️ Nyawa: <span id="nilaiNyawa">3</span></div>
</div>

<div id="kawasanPermainan">
    <div id="kapal">🚀</div>
    <div id="sinarHijau"></div>
    <div id="mesejTamat">
        <div id="teksTamat"></div>
        <button id="butangMulaSemula">🔄 MULAKAN SEMULA</button>
    </div>
</div>

<div id="kawalan">
    <div class="kumpul-kiriKanan">
        <button class="btn-kiriKanan" id="btnKiri">⬅️</button>
        <button class="btn-kiriKanan" id="btnKanan">➡️</button>
    </div>
    <button class="btn-tembak" id="btnTembak">🔫 TEMBAK</button>
</div>

<script>
let mata = 0;
let nyawa = 3;
let soalanSemasa = {};
let kelajuanKapal = 6;
let peluruAktif = [];
let sasaranWatak = [];
let sedangGerakKiri = false;
let sedangGerakKanan = false;

const kapal = document.getElementById("kapal");
const kawasan = document.getElementById("kawasanPermainan");
const sinarHijau = document.getElementById("sinarHijau");
const mesejTamat = document.getElementById("mesejTamat");
const teksTamat = document.getElementById("teksTamat");
const butangMulaSemula = document.getElementById("butangMulaSemula");

// Fungsi Mulakan Semula
butangMulaSemula.addEventListener("click", () => {
    mata = 0;
    nyawa = 3;
    kemasKiniStatus();
    mesejTamat.style.display = "none";
    sinarHijau.style.opacity = "0";
    soalanBaharu();
});

// Bunyi ringkas
function mainBunyi(jenis){
    try {
        let bunyi = new AudioContext();
        let pembuat = bunyi.createOscillator();
        let isipadu = bunyi.createGain();
        pembuat.connect(isipadu); isipadu.connect(bunyi.destination);
        if(jenis === "tembak"){ pembuat.type="sawtooth"; pembuat.frequency.value=1200; isipadu.gain.setValueAtTime(0.1,bunyi.currentTime); isipadu.gain.exponentialRampToValueAtTime(0.01,bunyi.currentTime+0.1); pembuat.start(); pembuat.stop(bunyi.currentTime+0.1); }
        else if(jenis === "betul"){ pembuat.type="sine"; pembuat.frequency.value=523; isipadu.gain.setValueAtTime(0.15,bunyi.currentTime); pembuat.start(); pembuat.frequency.setValueAtTime(784,bunyi.currentTime+0.2); isipadu.gain.exponentialRampToValueAtTime(0.01,bunyi.currentTime+0.3); pembuat.stop(bunyi.currentTime+0.3); }
        else if(jenis === "salah"){ pembuat.type="square"; pembuat.frequency.value=200; isipadu.gain.setValueAtTime(0.12,bunyi.currentTime); isipadu.gain.exponentialRampToValueAtTime(0.01,bunyi.currentTime+0.3); pembuat.start(); pembuat.stop(bunyi.currentTime+0.3); }
    } catch(e){}
}

// SENARAI SOALAN BAB 3: Kuasa Dua, Punca Kuasa Dua, Kuasa Tiga, Punca Kuasa Tiga
const senaraiSoalan = [
    {soalan:"2² = ?", betul:"4", salah:["6","8"]},
    {soalan:"5² = ?", betul:"25", salah:["10","20"]},
    {soalan:"7² = ?", betul:"49", salah:["14","42"]},
    {soalan:"10² = ?", betul:"100", salah:["20","50"]},
    {soalan:"12² = ?", betul:"144", salah:["24","120"]},
    {soalan:"0.3² = ?", betul:"0.09", salah:["0.9","0.009"]},
    {soalan:"√16 = ?", betul:"4", salah:["8","2"]},
    {soalan:"√36 = ?", betul:"6", salah:["18","12"]},
    {soalan:"√81 = ?", betul:"9", salah:["3","27"]},
    {soalan:"√121 = ?", betul:"11", salah:["12","22"]},
    {soalan:"√225 = ?", betul:"15", salah:["10","25"]},
    {soalan:"√(9/16) = ?", betul:"3/4", salah:["9/4","3/16"]},
    {soalan:"2³ = ?", betul:"8", salah:["6","4"]},
    {soalan:"3³ = ?", betul:"27", salah:["9","18"]},
    {soalan:"4³ = ?", betul:"64", salah:["12","32"]},
    {soalan:"5³ = ?", betul:"125", salah:["25","75"]},
    {soalan:"10³ = ?", betul:"1000", salah:["30","300"]},
    {soalan:"³√8 = ?", betul:"2", salah:["4","3"]},
    {soalan:"³√27 = ?", betul:"3", salah:["9","6"]},
    {soalan:"³√64 = ?", betul:"4", salah:["8","32"]},
    {soalan:"³√125 = ?", betul:"5", salah:["25","15"]},
    {soalan:"³√1000 = ?", betul:"10", salah:["100","33"]},
    {soalan:"³√(-8) = ?", betul:"-2", salah:["2","-4"]}
];

// Tambah Bintang Latar
function tambahBintang(){
    for(let i=0; i<30; i++){
        let bintang = document.createElement("div");
        bintang.className = "bintang";
        bintang.style.left = Math.random()*100 + "%";
        bintang.style.top = Math.random()*70 + "%";
        bintang.style.width = (1+Math.random()*2) + "px";
        bintang.style.height = bintang.style.width;
        kawasan.appendChild(bintang);
    }
}

// Kawalan Butang Skrin Sentuh
const btnKiri = document.getElementById("btnKiri");
const btnKanan = document.getElementById("btnKanan");
const btnTembak = document.getElementById("btnTembak");

btnKiri.addEventListener("touchstart", e=>{ e.preventDefault(); sedangGerakKiri = true; });
btnKiri.addEventListener("touchend", e=>{ e.preventDefault(); sedangGerakKiri = false; });
btnKanan.addEventListener("touchstart", e=>{ e.preventDefault(); sedangGerakKanan = true; });
btnKanan.addEventListener("touchend", e=>{ e.preventDefault(); sedangGerakKanan = false; });
btnTembak.addEventListener("touchstart", e=>{ e.preventDefault(); tembakPeluru(); });

// Kawalan Papan Kekunci
let kekunciDitekan = {};
document.addEventListener("keydown", e=>{ kekunciDitekan[e.code] = true; });
document.addEventListener("keyup", e=>{ kekunciDitekan[e.code] = false; });

// Fungsi Tembak
function tembakPeluru(){
    mainBunyi("tembak");
    let peluru = document.createElement("div");
    peluru.className = "peluru";
    let posisiKapal = kapal.offsetLeft + kapal.offsetWidth/2 - 4;
    peluru.style.left = posisiKapal + "px";
    peluru.style.bottom = "140px";
    kawasan.appendChild(peluru);
    peluruAktif.push(peluru);
}

// Bersihkan kawasan sepenuhnya sebelum buat pusingan baharu
function soalanBaharu(){
    const kapalSimpan = document.getElementById("kapal");
    const sinarSimpan = document.getElementById("sinarHijau");
    const mesejSimpan = document.getElementById("mesejTamat");
    
    kawasan.innerHTML = "";
    
    kawasan.appendChild(kapalSimpan);
    kawasan.appendChild(sinarSimpan);
    kawasan.appendChild(mesejSimpan);
    
    sasaranWatak = [];
    peluruAktif = [];
    
    tambahBintang();

    soalanSemasa = senaraiSoalan[Math.floor(Math.random()*senaraiSoalan.length)];
    document.getElementById("skrinSoalan").textContent = soalanSemasa.soalan;

    let senaraiJawapan = [soalanSemasa.betul, ...soalanSemasa.salah];
    senaraiJawapan.sort(()=> Math.random()-0.5);

    senaraiJawapan.forEach((jawapan, indeks)=>{
        let watak = document.createElement("div");
        watak.className = "watak";
        let lebarKawasan = kawasan.clientWidth;
        let jarak = lebarKawasan / 4;
        watak.style.left = (jarak * (indeks+1) - 35) + "px";
        watak.style.top = "40px";
        watak.innerHTML = `<div class='kotak-jawapan'>${jawapan}</div>👨‍🚀`;
        kawasan.appendChild(watak);
        sasaranWatak.push({elemen:watak, jawapan:jawapan});
    });
}

// Semak pertembungan peluru
function semakLindas(){
    peluruAktif = peluruAktif.filter(peluru=>{
        let posPeluru = peluru.getBoundingClientRect();
        let kena = false;

        sasaranWatak.forEach(sasaran=>{
            if(!sasaran.elemen) return;
            
            let posSasaran = sasaran.elemen.getBoundingClientRect();
            if(posPeluru.left < posSasaran.right && posPeluru.right > posSasaran.left &&
               posPeluru.top < posSasaran.bottom && posPeluru.bottom > posSasaran.top){
                kena = true; 
                peluru.remove();

                let letupan = document.createElement("div");
                letupan.className = "kesan-letupan";
                letupan.style.left = sasaran.elemen.offsetLeft + "px";
                letupan.style.top = sasaran.elemen.offsetTop + "px";
                kawasan.appendChild(letupan); 
                setTimeout(()=> letupan.remove(), 400);

                if(sasaran.jawapan === soalanSemasa.betul){ 
                    mata += 10; 
                    mainBunyi("betul"); 
                    if(mata>=100) return tamatPermainan(true);
                } else { 
                    nyawa--; 
                    mainBunyi("salah"); 
                    if(nyawa<=0) return tamatPermainan(false);
                }

                kemasKiniStatus();
                soalanBaharu();
            }
        });

        if(!kena){
            let btm = parseInt(peluru.style.bottom || 140);
            peluru.style.bottom = (btm + 10) + "px";
            if(btm > kawasan.clientHeight) peluru.remove();
        } 
        return !kena;
    });
}

// Gelung utama permainan
function larianUtama(){
    if(sedangGerakKiri || kekunciDitekan["ArrowLeft"]) if(kapal.offsetLeft > 5) kapal.style.left = (kapal.offsetLeft - kelajuanKapal) + "px";
    if(sedangGerakKanan || kekunciDitekan["ArrowRight"]) if(kapal.offsetLeft < kawasan.clientWidth - 65) kapal.style.left = (kapal.offsetLeft + kelajuanKapal) + "px";
    if(kekunciDitekan["Space"]) tembakPeluru();
    semakLindas();
    requestAnimationFrame(larianUtama);
}

// Paparan mesej tamat
function tamatPermainan(menang){
    if(!menang){ 
        sinarHijau.style.opacity = "0.9"; 
        teksTamat.innerHTML = "💥 Ditembak Sinar Hijau!<br>Kalah..."; 
    } else { 
        teksTamat.innerHTML = "🎉 MISI BERJAYA!<br>Anda Menang!"; 
    }
    mesejTamat.style.display = "block";
}

function kemasKiniStatus(){
    document.getElementById("nilaiMata").textContent = mata;
    document.getElementById("nilaiNyawa").textContent = nyawa;
}

// Mula permainan
soalanBaharu();
larianUtama();
</script>
</body>
</html>

Game Source: Galaksi Penyamaran - Bab 3

Creator: DriftGlider72

Libraries: none

Complexity: complex (359 lines, 13.9 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: galaksi-penyamaran-bab-3-driftglider72" to link back to the original. Then publish at arcadelab.ai/publish.