2025-11-26 21:28:34 +07:00

369 lines
10 KiB
HTML

<!DOCTYPE html>
<!--Code by GameDev Freddie - Youtube.com/@GameDev-Freddie-->
<html>
<head>
<style>
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;
}
</style>
</head>
<body>
<header>
<div class="centered">
<div class="icon"></div>
<h1>Snake</h1>
</div>
</header>
<div class="HalamanFull">
<canvas width="1058" height="480" id="game"></canvas>
<div id="gameover" class="gameover"></div>
<div>
<div class="text">Controls: <br />Movement: W A S D <br /><br /></div>
<div id="text" class="text"></div>
</div>
</div>
<script>
//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 +
"<br>Highscore: " +
highscore +
"<br>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();
</script>
<footer class="centered">
<div class="centered">
<p></p>
</div>
</footer>
</body>
</html>