// //bagian tempat main ama buat generate game 2d var canvas = document.getElementById("game"); var content = canvas.getContext("2d"); const Text = document.getElementById("text"); const UpDead = document.getElementById("gameover-overlay"); const ScoreMain = document.getElementById("gameover-score"); const PlayAgain = document.getElementById("ulangi"); const Udahan = document.getElementById("keluar"); //settingan awal var grid = 24; var count = 0; var speed = 10; var score = 0; var highscore = 0; var ArahUlar = 0; var GameOverTimer = 0; var GameStart = false; var ModeH = false; const persiapan = document.getElementById("start"); //generate gambar external //kepala const kepala = {   kanan: new Image(),   kiri: new Image(),   atas: new Image(),   bawah: new Image(), }; kepala.kanan.src = "image/KepalaHorizontalKanan.png"; kepala.kiri.src  = "image/KepalaHorizontalKiri.png"; kepala.atas.src    = "image/KepalaVertikalAtas.png"; kepala.bawah.src  = "image/KepalaVertikalBawah.png"; //badan const badan = {   horizontal: new Image(),   vertical: new Image(), }; badan.horizontal.src = "image/BadanHorizontal.png"; badan.vertical.src   = "image/BadanVertikal.png"; //const beluk const belok = {   AtasKanan: new Image(),   AtasKiri: new Image(),   BawahKanan: new Image(),   BawahKiri: new Image(), }; belok.AtasKanan.src   = "image/BelokAtasKanan.png"; belok.AtasKiri.src    = "image/BelokAtasKiri.png"; belok.BawahKanan.src = "image/BelokBawahKanan.png"; belok.BawahKiri.src  = "image/BelokBawahKiri.png"; //bokong const bokong = {   kanan: new Image(),   kiri: new Image(),   atas: new Image(),   bawah: new Image(), }; bokong.kanan.src = "image/BokongHorizontalKanan.png"; bokong.kiri.src  = "image/BokongHorizontalKiri.png"; bokong.atas.src    = "image/BokongVertikalAtas.png"; bokong.bawah.src  = "image/BokongVertikalBawah.png"; var ApelImage = new Image(); ApelImage.src = "image/ApelLayer.png"; var TembokImage = new Image(); TembokImage.src = "image/Tembok.png"; //set posisi ular dan Apel var Ular = { x: 528, y: 240, dx: grid, dy: 0, cells: [], maxCells: 4 }; var Apel = { x: 0, y: 0 }; var Tembok = []; UpdateScore(0); RandomizeApel(); //buat ngatur batu spwan apa ga nanti const halaman = document.querySelector(".HalamanFull"); const gameCanvas = document.getElementById("game"); document.getElementById("mode-normal").addEventListener("click", function () { halaman.style.backgroundImage ='url("halamanFull/cherryBlossom.png")'; halaman.style.setProperty("--overlay-opacity", "0.4"); gameCanvas.style.filter = "brightness(1)"; StartingGame(false); }); document.getElementById("mode-tambahan").addEventListener("click", function () { halaman.style.backgroundImage ='url("halamanFull/cherryBlossomNight.png")'; halaman.style.setProperty("--overlay-opacity", "0.7"); gameCanvas.style.filter = "brightness(0.5)"; StartingGame(true); }); function getDirection(cell1, cell2) {     if (cell2.x > cell1.x) return "kanan";     if (cell2.x < cell1.x) return "kiri";     if (cell2.y > cell1.y) return "bawah";     if (cell2.y < cell1.y) return "atas";     return null; } //ngatur biar game ga langsung jalan function StartingGame(menantang) {     ModeH = menantang;     persiapan.style.display = "none";     if (ModeH) {         RandomSpawnWall();     } else {         Tembok = [];     }     GameStart = true; } //buat ngatur batu spwan apa ga nanti document.getElementById("mode-normal").addEventListener("click", function () {     StartingGame(false); }); document.getElementById("mode-tambahan").addEventListener("click", function () {     StartingGame(true); }); //play again pas gameover function resetGame() {     Ular.x = 528;     Ular.y = 240;     Ular.cells = [];     Ular.maxCells = 4;     Ular.dx = grid;     Ular.dy = 0;     Tembok = [];     RandomizeApel();     UpdateScore(0); } //ngatur tombol pas gameover kemana abis di klik PlayAgain.addEventListener("click", function () {     UpDead.style.display = "none";     resetGame();     ModeH = false;     persiapan.style.display = "flex"; }); Udahan.addEventListener("click", function () {     UpDead.style.display = "none";     resetGame();     ModeH = false; }); //gameover terus ngatur ular ke setting awal function gameLoop() {     if (!GameStart) {         requestAnimationFrame(gameLoop);         return;     }     ClearCanvas();     Movement();     IntiGame();     requestAnimationFrame(gameLoop); } //random spawn Apel function RandomizeApel() {     var pembataslebar = Math.floor(canvas.width / grid);     var pembatastinggi = Math.floor(canvas.height / grid);         do {         Apel.x = Math.floor(Math.random() * pembataslebar) * grid;         Apel.y = Math.floor(Math.random() * pembatastinggi) * grid;                 //mastiin Apel gak spawn di atas ular         var isOverlapSnake = Ular.cells.some(cell => cell.x === Apel.x && cell.y === Apel.y);                 //mastiin Apel gak spawn di atas tembok         var isOverlapWall = Tembok.some(bata => bata.x === Apel.x && bata.y === Apel.y);     } while (isOverlapSnake || isOverlapWall); } //random spawn tembok function RandomSpawnWall() {     var TembokX, TembokY;     var kosong;     var pembataslebar = Math.floor(canvas.width / grid);     var pembatastinggi = Math.floor(canvas.height / grid);     //create tembok     do {         kosong = true;         TembokX = Math.floor(Math.random() * pembataslebar) * grid;         TembokY = Math.floor(Math.random() * pembatastinggi) * grid;         //cek untuk posisi yang mau di kasih tembok ada/tidak ada ularnya         for (var i = 0; i < Ular.cells.length; i++) {             if (Math.abs(Ular.cells[i].x - TembokX) <= grid * 5 && Math.abs(Ular.cells[i].y - TembokY) <= grid * 5) {                 kosong = false;                 break;             }         }         // tidak memperbolehkan tembok spawn sama dengan apel         if (TembokX === Apel.x && TembokY === Apel.y) {             kosong = false;         }         //cek agar tembok tidak menumpuk         for (var i = 0; i < Tembok.length; i++) {             if (Tembok[i].x === TembokX && Tembok[i].y === TembokY) {                 kosong = false;                 break;             }         }     } while (kosong === false);     Tembok.push({ x: TembokX, y: TembokY }); } //nambah tembok tiap score kelipatan function PenambahanTembok() {     if (ModeH) {         if (score > 0 && score % 2 === 0 && Tembok.length < 15 && Tembok.length < score / 2) {              RandomSpawnWall();         }     } } //set dan update score function UpdateScore(amount, addToScore = true) { if (addToScore) { score = amount > 0 ? score + amount : 0; } console.log("UPDATE SCORE , score:",score); highscore = score > highscore ? score : highscore; Text.innerHTML = "Score: " + score + "
Highscore: " + highscore + "
Speed: " + speed; if (addToScore) {     PenambahanTembok(); } } //tampilin gameover function GameOver() { GameStart = false; ClearCanvas(); // Simpan score ke database saveScore(score); // TAMPILKAN POP-UP GAME OVER ScoreMain.innerHTML = "Score: " + score; UpDead.style.display = "flex"; } //fungsi untuk menyimpan score ke database function saveScore(finalScore) { console.log("SAVING SCORE , score:",finalScore); // Buat form tersembunyi untuk submit score var form = document.createElement('form'); form.method = 'POST'; form.action = 'simpan_score.php'; form.style.display = 'none'; var scoreInput = document.createElement('input'); scoreInput.type = 'hidden'; scoreInput.name = 'score'; scoreInput.value = finalScore; form.appendChild(scoreInput); document.body.appendChild(form); form.submit(); } //reset isi canvas doang function ClearCanvas() {     content.clearRect(0, 0, canvas.width, canvas.height); } //bagian utama: //ular makan dan mati pas ketemu badannya function IntiGame() {     // buat gambarnya bisa keluar     content.drawImage(ApelImage, Apel.x, Apel.y, grid, grid);         // Gambar Tembok     Tembok.forEach(function (bata) {         content.drawImage(TembokImage, bata.x, bata.y, grid, grid);     });     // Gambar Ular Ular.cells.forEach(function (cell, index) {     var gambarUlar = null;     //pala ulo     if (index === 0) {         if (Ular.dx === grid) gambarUlar = kepala.kanan;         else if (Ular.dx === -grid) gambarUlar = kepala.kiri;         else if (Ular.dy === -grid) gambarUlar = kepala.atas;         else if (Ular.dy === grid) gambarUlar = kepala.bawah;     }     //bokong     else if (index === Ular.cells.length - 1) {         var sebelum = Ular.cells[index - 1];         var arahEkor = getDirection(sebelum, cell);         if (arahEkor === "kanan") gambarUlar = bokong.kanan;         else if (arahEkor === "kiri") gambarUlar = bokong.kiri;         else if (arahEkor === "atas") gambarUlar = bokong.atas;         else if (arahEkor === "bawah") gambarUlar = bokong.bawah;     }     //badan     else {         var sebelum = Ular.cells[index - 1];         var sesudah = Ular.cells[index + 1];         var ArahMasuk = getDirection(sebelum, cell);         var ArahKeluar = getDirection(cell, sesudah);         if (ArahMasuk && ArahKeluar) {         if (ArahMasuk === ArahKeluar) {             // Badan Lurus (Horizontal/Vertical)             if (ArahMasuk === "kiri" || ArahMasuk === "kanan") {                 gambarUlar = badan.horizontal;             } else {                 gambarUlar = badan.vertical;             }         }     else { // belok AtasKanan             if ((ArahMasuk === "bawah" && ArahKeluar === "kanan") || (ArahMasuk === "kiri" && ArahKeluar === "atas")) gambarUlar = belok.AtasKanan;             // belok AtasKiri else if ((ArahMasuk === "bawah" && ArahKeluar === "kiri") || (ArahMasuk === "kanan" && ArahKeluar === "atas")) gambarUlar = belok.AtasKiri;             // belok BawahKanan else if ((ArahMasuk === "atas" && ArahKeluar === "kanan") || (ArahMasuk === "kiri" && ArahKeluar === "bawah")) gambarUlar = belok.BawahKanan;             // belok BawahKiri else if ((ArahMasuk === "atas" && ArahKeluar === "kiri") || (ArahMasuk === "kanan" && ArahKeluar === "bawah")) gambarUlar = belok.BawahKiri;     }     }     }     if (gambarUlar) {         content.drawImage(gambarUlar, cell.x, cell.y, grid, grid);     } //ular makan apel if (index === 0) {     if (cell.x === Apel.x && cell.y === Apel.y) {         Ular.maxCells += 1;         UpdateScore(1, true);         RandomizeApel();     }     //nabrak tembok     Tembok.forEach(function (bata) {         if (cell.x === bata.x && cell.y === bata.y) {             GameOver();         }     });     //nabrak diri e dw     for (var i = 1; i < Ular.cells.length; i++) {         if (cell.x === Ular.cells[i].x && cell.y === Ular.cells[i].y) {             GameOver();         }     }     }     }); } //update speed kalau score update function Movement() {     if (++count < speed) return;     if (ArahUlar > 0) ArahUlar--;     count = 0;         Ular.x += Ular.dx;     Ular.y += Ular.dy;         if (         Ular.x < 0 ||         Ular.x >= canvas.width ||         Ular.y < 0 ||         Ular.y >= canvas.height     )         GameOver();             Ular.cells.unshift({ x: Ular.x, y: Ular.y });     if (Ular.cells.length > Ular.maxCells) Ular.cells.pop(); } //input keyboard function InputKeyboard() {     document.addEventListener("keydown", function (e) {         if (!GameStart) return;         if (             ArahUlar == 0 &&             ((e.code == "KeyA" && Ular.dx === 0) ||                 (e.code == "KeyD" && Ular.dx === 0))         ) {             ArahUlar = 1;             Ular.dx = e.code === "KeyA" ? -grid : grid;             Ular.dy = 0;         }         else if (             ArahUlar == 0 &&             ((e.code === "KeyW" && Ular.dy === 0) ||                 (e.code == "KeyS" && Ular.dy === 0))         ) {             ArahUlar = 1;             Ular.dy = e.code == "KeyW" ? -grid : grid;             Ular.dx = 0;         }         else if (             ArahUlar == 0 &&             ((e.code === "ArrowUp" && Ular.dy === 0) ||                 (e.code == "ArrowDown" && Ular.dy === 0))         ) {             ArahUlar = 1;             Ular.dy = e.code == "ArrowUp" ? -grid : grid;             Ular.dx = 0;         }         else if (             ArahUlar == 0 &&             ((e.code === "ArrowLeft" && Ular.dx === 0) ||                 (e.code == "ArrowRight" && Ular.dx === 0))         ) {             ArahUlar = 1;             Ular.dx = e.code == "ArrowLeft" ? -grid : grid;             Ular.dy = 0;         }         if (e.code === "KeyE" || e.code == "KeyQ") {             speed =                 e.code == "KeyE" && speed > 5                     ? speed - 1                     : e.code == "KeyQ" && speed < 20                     ? speed + 1                     : speed; // Panggil UpdateScore hanya untuk memperbarui teks di layar, bukan skornya UpdateScore(0, false); }     }); } InputKeyboard(); gameLoop();