diff --git a/GameLogic.js b/GameLogic.js new file mode 100644 index 0000000..e32a22d --- /dev/null +++ b/GameLogic.js @@ -0,0 +1,271 @@ + //bagian tempat main ama buat generate game 2d + var canvas = document.getElementById("game"); + var content = canvas.getContext("2d"); + const Text = document.getElementById("text"); + const GameoverText = document.getElementById("gameover"); + + //settingan awal + var grid = 16; + var count = 0; + var speed = 8; + var score = 0; + var highscore = 0; + var ArahUlar = 0; + var GameOverTimer = 0; + + //generate gambar external + var KepalaUlarImage = new Image(); + KepalaUlarImage.src = "image/KepalaHorizontalKanan.png"; + var KepalAtas = new Image(); + KepalAtas.src = "image/KepalaVertikalAtas.png"; + var KepalaBawah = new Image(); + KepalaBawah.src = "image/KepalaVertikalBawah.png"; + var KepalaKiri = new Image(); + KepalaKiri.src = "image/KepalaHorizontalKiri.png"; + var KepalaKanan = new Image(); + KepalaKanan.src = "image/KepalaHorizontalKanan.png"; + // ↑ kepala ular + + var BadanUlarImage = new Image(); + BadanUlarImage.src = "image/BadanVertikal.png"; + // ↑ badan ular + + var ApelImage = new Image(); + ApelImage.src = "image/ApelLayer.png"; // Apel + var TembokImage = new Image(); + TembokImage.src = "image/Tembok.png"; // Tembok Batagor + + //D:\PROYEK UAS\Game ULAR\gambar\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(); + RandomSpawnWall(); + + //mastiin gambar external generate dulu sebelum game start + KepalaUlarImage.onload = function () { + function gameLoop() {} + }; + + //gameover terus ngatur ular ke setting awal + function gameLoop() { + if (GameOverTimer > 0) { + GameOverTimer -= 0.006; + GameoverText.innerHTML = + GameOverTimer > 0 + ? "Gameover " + GameOverTimer.toFixed(0).toString() + : ""; + if (GameOverTimer <= 0) { + Ular.x = 528; + Ular.y = 240; + Ular.cells = []; + Ular.maxCells = 4; + Ular.dx = grid; + Ular.dy = 0; + Tembok = []; + RandomizeApel(); + UpdateScore(0); + RandomSpawnWall(); + } + } else { + InputKeyboard(); + ClearCanvas(); + Movement(); + IntiGame(); + } + requestAnimationFrame(gameLoop); + } + + //random spawn Apel + function RandomizeApel() { + var pembataslebar = Math.floor(canvas.width / grid); + var pembatastinggi = Math.floor(canvas.height / grid); + Apel.x = Math.floor(Math.random() * pembataslebar) * grid; + Apel.y = Math.floor(Math.random() * pembatastinggi) * grid; + } + + 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 (Ular.cells[i].x === TembokX && Ular.cells[i].y === TembokY) { + kosong = false; + break; + } + } + + //tidak memperbolehkan tembok spawn sama dengan apel + if (TembokX === Apel.x && TembokY === Apel.y) { + kosong = false; + } + + 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 ... berapa enaknya ya? 😁 + function PenambahanTembok() { + if (Tembok.length < Math.floor(score / 2)) { + RandomSpawnWall(); + } + } + + //set dan update score + function UpdateScore(amount) { + score = amount > 0 ? score + amount : 0; + highscore = score > highscore ? score : highscore; + Text.innerHTML = + "Score: " + + score + + "
Highscore: " + + highscore + + "
Speed: " + + speed; + + PenambahanTembok(); + } + + //gameover countdown + function GameOver() { + GameOverTimer = 3; + } + + //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); + Tembok.forEach(function (bata) { + content.drawImage(TembokImage, bata.x, bata.y, grid, grid); + }); + + Ular.cells.forEach(function (cell, index) { + if (index === 0) { + // Logika Pemilihan Gambar Kepala Ular + var posisiKepalaImage; + if (Ular.dx === grid) { + // KANAN + posisiKepalaImage = KepalaKanan; + } else if (Ular.dx === -grid) { + // KIRI + posisiKepalaImage = KepalaKiri; + } else if (Ular.dy === -grid) { + // ATAS + posisiKepalaImage = KepalAtas; + } else if (Ular.dy === grid) { + // BAWAH + posisiKepalaImage = KepalaBawah; + } else { + // Default, misalnya saat game baru mulai (dx=grid, dy=0, atau default awal) + posisiKepalaImage = KepalaKanan; + } + + content.drawImage(posisiKepalaImage, cell.x, cell.y, grid, grid); + } else { + content.drawImage(BadanUlarImage, cell.x, cell.y, grid, grid); + } + }); + + //bagian generate ular + Ular.cells.forEach(function (cell, index) { + if (index === 0) { + content.drawImage(KepalaUlarImage, cell.x, cell.y, grid, grid); + } else { + content.drawImage(BadanUlarImage, cell.x, cell.y, grid, grid); + } + + //buat pas ular makan Apel + if (cell.x === Apel.x && cell.y === Apel.y) { + Ular.maxCells += 1; + UpdateScore(1); + RandomizeApel(); + } + + //tabrak tembok = mati + if (index === 0) { + Tembok.forEach(function (bata) { + if (cell.x === bata.x && cell.y === bata.y) { + GameOver(); + } + }); + } + + //buat pas ular mati kena badan sendiri + for (var i = index + 1; i < Ular.cells.length; i++) + if (cell.x === Ular.cells[i].x && cell.y === Ular.cells[i].y) + GameOver(); + }); + } + + 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 buat jalan + function InputKeyboard() { + document.addEventListener("keydown", function (e) { + 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; + } + if (e.code === "KeyE" || e.code == "KeyQ") + speed = + e.code == "KeyE" && speed > 4 + ? speed - 1 + : e.code == "KeyQ" && speed < 9 + ? speed + 1 + : speed; + }); + } + gameLoop(); \ No newline at end of file diff --git a/GameStyle.css b/GameStyle.css new file mode 100644 index 0000000..80abb67 --- /dev/null +++ b/GameStyle.css @@ -0,0 +1,63 @@ + body { + background-color: rgb(24, 24, 24); + color: white; + text-align: left; + font-family: "Comic Sans MS", cursive, sans-serif; + font-size: 24px; + } + header, + footer, + .HalamanFull { + padding-left: 50px; + padding-right: 50px; + } + header, + footer { + background-color: rgb(18, 18, 18); + display: flex; + align-items: center; + justify-content: space-between; + } + .HalamanFull { + background-color: rgb(28, 28, 28); + color: white; + height: 100%; + display: flex; + align-items: left; + justify-content: left; + padding-bottom: 20px; + padding-top: 20px; + } + .icon { + width: 70px; + height: 70px; + background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/Nazi_Swastika.svg/2048px-Nazi_Swastika.svg.png"); + background-size: cover; + margin-right: 20px; + margin-left: 20px; + } + .centered { + display: flex; + align-items: center; + justify-content: center; + } + h1 { + font-size: 40px; + margin-right: 100px; + } + .text { + padding-top: 30px; + padding-left: 50px; + color: white; + } + #gameover { + color: red; + font-size: 90px; + position: absolute; + top: 280px; + left: 300px; + } + #game { + background: rgb(192, 232, 255); + border: 1px solid white; + } \ No newline at end of file diff --git a/game.html b/game.html index 2e2580c..ba9cf1b 100644 --- a/game.html +++ b/game.html @@ -1,74 +1,10 @@ - - - + + +
@@ -76,6 +12,7 @@
+
@@ -85,284 +22,13 @@
- - + + +