Meta Description" name="description" />
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Sky Patrol - Fighter Interceptor</title>
<style>
body {
margin: 0;
padding: 0;
background: #050510;
overflow: hidden;
font-family: sans-serif;
color: white;
user-select: none;
}
#gameCanvas {
display: block;
margin: 0 auto;
background: linear-gradient(to bottom, #0b1d3a, #1f4068);
box-shadow: 0 0 20px rgba(0,0,0,0.8);
}
#ui {
position: absolute;
top: 10px;
left: 50%;
transform: translateX(-50%);
width: 90%;
max-width: 400px;
display: flex;
justify-content: space-between;
font-size: 18px;
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
pointer-events: none;
}
#gameOverScreen {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
background: rgba(0, 0, 0, 0.85);
padding: 30px;
border-radius: 10px;
border: 2px solid #e43f5a;
width: 80%;
max-width: 300px;
}
button {
background: #e43f5a;
color: white;
border: none;
padding: 12px 25px;
font-size: 16px;
font-weight: bold;
border-radius: 5px;
cursor: pointer;
margin-top: 15px;
}
button:active {
background: #a82c41;
}
#controls-hint {
position: absolute;
bottom: 15px;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
opacity: 0.6;
text-align: center;
pointer-events: none;
width: 100%;
}
</style>
</head>
<body>
<div id="ui">
<div id="scoreId">SKOR: 0</div>
<div id="hpId">NYAWA: ❤️❤️❤️</div>
</div>
<div id="gameOverScreen">
<h2 style="color: #e43f5a; margin-top:0;">GAME OVER</h2>
<p id="finalScore">Skor Akhir: 0</p>
<button onclick="resetGame()">MAIN LAGI</button>
</div>
<div id="controls-hint">HP: Sentuh sisi kanan/kiri layar | Laptop: Pake Panah Kanan/Kiri</div>
<canvas id="gameCanvas"></canvas>
<script>
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
// Responsif ukuran layar
const canvasWidth = Math.min(window.innerWidth, 450);
const canvasHeight = window.innerHeight;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
let score = 0;
let lives = 3;
let gameOver = false;
// Player (Pesawat Tempur Utama)
const player = {
x: canvasWidth / 2 - 20,
y: canvasHeight - 100,
width: 40,
height: 45,
speed: 7,
movingLeft: false,
movingRight: false
};
let bullets = [];
let enemies = [];
let shootTimer = 0;
let enemyTimer = 0;
// Kontrol Keyboard (Laptop)
window.addEventListener("keydown", (e) => {
if (e.key === "ArrowLeft") player.movingLeft = true;
if (e.key === "ArrowRight") player.movingRight = true;
});
window.addEventListener("keyup", (e) => {
if (e.key === "ArrowLeft") player.movingLeft = false;
if (e.key === "ArrowRight") player.movingRight = false;
});
// Kontrol Touchscreen (HP)
window.addEventListener("touchstart", (e) => {
const touchX = e.touches[0].clientX;
if (touchX < window.innerWidth / 2) {
player.movingLeft = true;
} else {
player.movingRight = true;
}
});
window.addEventListener("touchend", () => {
player.movingLeft = false;
player.movingRight = false;
});
function spawnEnemy() {
const size = Math.random() * (40 - 25) + 25;
const x = Math.random() * (canvasWidth - size);
enemies.push({
x: x,
y: -size,
width: size,
height: size,
speed: Math.random() * (4 - 2) + 2
});
}
function drawPlayer() {
ctx.fillStyle = "#00bcd4"; // Warna pesawat sekutu (Cyan)
ctx.beginPath();
ctx.moveTo(player.x + player.width / 2, player.y); // Hidung pesawat
ctx.lineTo(player.x, player.y + player.height); // Sayap kiri
ctx.lineTo(player.x + player.width / 2, player.y + player.height - 10); // Buritan
ctx.lineTo(player.x + player.width, player.y + player.height); // Sayap kanan
ctx.closePath();
ctx.fill();
}
function update() {
if (gameOver) return;
// Pergerakan pemain
if (player.movingLeft && player.x > 0) player.x -= player.speed;
if (player.movingRight && player.x < canvasWidth - player.width) player.x += player.speed;
// Auto-tembak peluru
shootTimer++;
if (shootTimer >= 15) {
bullets.push({ x: player.x + player.width / 2 - 2, y: player.y, width: 4, height: 12, speed: 9 });
shootTimer = 0;
}
// Gerakan Peluru
for (let i = bullets.length - 1; i >= 0; i--) {
bullets[i].y -= bullets[i].speed;
if (bullets[i].y < 0) bullets.splice(i, 1);
}
// Munculin musuh
enemyTimer++;
if (enemyTimer >= 40) {
spawnEnemy();
enemyTimer = 0;
}
// Gerakan Musuh & Cek Tabrakan
for (let i = enemies.length - 1; i >= 0; i--) {
enemies[i].y += enemies[i].speed;
// Lewat batas bawah (Lolos)
if (enemies[i].y > canvasHeight) {
enemies.splice(i, 1);
lives--;
updateUI();
continue;
}
// Tabrakan dengan Pesawat Pemain
if (
enemies[i].x < player.x + player.width &&
enemies[i].x + enemies[i].width > player.x &&
enemies[i].y < player.y + player.height &&
enemies[i].y + enemies[i].height > player.y
) {
enemies.splice(i, 1);
lives--;
updateUI();
continue;
}
// Tabrakan dengan Peluru
for (let j = bullets.length - 1; j >= 0; j--) {
if (
bullets[j].x < enemies[i].x + enemies[i].width &&
bullets[j].x + bullets[j].width > enemies[i].x &&
bullets[j].y < enemies[i].y + enemies[i].height &&
bullets[j].y + bullets[j].height > enemies[i].y
) {
enemies.splice(i, 1);
bullets.splice(j, 1);
score += 10;
updateUI();
break;
}
}
}
if (lives <= 0) {
gameOver = true;
document.getElementById("gameOverScreen").style.display = "block";
document.getElementById("finalScore").innerText = "Skor Akhir: " + score;
}
}
function draw() {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
// Gambar Peluru
ctx.fillStyle = "#ffeb3b";
bullets.forEach(b => ctx.fillRect(b.x, b.y, b.width, b.height));
// Gambar Musuh (Target Merah)
ctx.fillStyle = "#e43f5a";
enemies.forEach(e => {
ctx.beginPath();
ctx.moveTo(e.x + e.width/2, e.y + e.height);
ctx.lineTo(e.x, e.y);
ctx.lineTo(e.x + e.width, e.y);
ctx.closePath();
ctx.fill();
});
// Gambar Pemain
drawPlayer();
}
function updateUI() {
document.getElementById("scoreId").innerText = "SKOR: " + score;
let heartStr = "NYAWA: ";
for (let i = 0; i < 3; i++) {
heartStr += i < lives ? "❤️" : "🖤";
}
document.getElementById("hpId").innerText = heartStr;
}
function resetGame() {
score = 0;
lives = 3;
gameOver = false;
bullets = [];
enemies = [];
player.x = canvasWidth / 2 - 20;
document.getElementById("gameOverScreen").style.style.display = "none";
updateUI();
}
function gameLoop() {
update();
draw();
requestAnimationFrame(gameLoop);
}
updateUI();
gameLoop();
</script>
</body>
</html>
1
1
10KB
10KB
106.0ms
192.0ms
106.0ms