kelompok06-2048/2048_Controls.js
Jevinca Marvella 4243584706 Coment section
2025-12-16 01:25:10 +07:00

117 lines
3.5 KiB
JavaScript

/* ==========================================
2048 CONTROLS
==========================================
fungsi utama:
1. handleKey() - mendeteksi keyboard (Arrow/WASD)
2. Touch Events - meneteksi swipe mobile
3. inputLocked - prevent konflik saat panel volume buka
========================================== */
// flag untuk blokir input game saat setting panel aktif
let inputLocked = false;
/* ==========================================
KEYBOARD INPUT HANDLER
========================================== */
function handleKey(e) {
// Blokir input kalau:
// 1. Tile sedang bergerak (isMoving = true)
// 2. Panel volume sedang dibuka (inputLocked = true)
if (isMoving || inputLocked) return;
let moved = false;
const k = e.key;
// Deteksi 4 arah: Arrow keys atau WASD
if (k === "ArrowLeft" || k === "a" || k === "A") {
e.preventDefault(); // Cegah scroll halaman
moved = moveLeft(); }
else if (k === "ArrowRight" || k === "d" || k === "D") {
e.preventDefault();
moved = moveRight(); }
else if (k === "ArrowUp" || k === "w" || k === "W") {
e.preventDefault();
moved = moveUp(); }
else if (k === "ArrowDown" || k === "s" || k === "S") {
e.preventDefault();
moved = moveDown(); }
// Kalau tile berhasil bergerak
if (moved) {
isMoving = true; // Lock input biar nggak spam
// Delay 100ms untuk animasi selesai
setTimeout(() => {
const added = addNewTile(); // Spawn tile baru
// Cek game over: board penuh ATAU nggak bisa move
if (!added || !canMove()) {
setTimeout(() => showGameOver(), 300);
}
isMoving = false; // Unlock input
}, 100);
} else {
//Invalid move - Kasih feedback shake
const b = document.getElementById("board");
if (b) {
b.classList.add("shake");
setTimeout(()=>b.classList.remove("shake"), 400);
}
}
}
/* ==========================================
TOUCH/SWIPE INPUT HANDLER (Mobile)
========================================== */
// Simpan posisi saat awal sentuhan
let touchStartX = 0;
let touchStartY = 0;
// Event 1: Catat posisi awal saat jari menyentuh layar
document.addEventListener("touchstart", function (e) {
if (inputLocked) return; // Jangan catat swipe kalau panel volume aktif
const t = e.touches[0];
touchStartX = t.clientX; // Posisi X awal
touchStartY = t.clientY; // Posisi Y awal
}, { passive: true }); // Passive = performa lebih smooth
// Event 2: Deteksi arah swipe saat jari diangkat
document.addEventListener("touchend", function (e) {
if (isMoving || inputLocked) return; // cek isMoving DAN inputLocked
const t = e.changedTouches[0];
// Hitung selisih posisi (delta)
const dx = t.clientX - touchStartX; //Horizontal movement
const dy = t.clientY - touchStartY; //Vertical movement
let moved = false;
// Tentukan arah swipe berdasarkan delta terbesar
if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 30) {
// Swipe HORIZONTAL (kiri/kanan)
// Minimal 30px biar nggak terlalu sensitif
if (dx > 0) moved = moveRight(); // swipe kanan
else moved = moveLeft(); // swipe kiri
} else if (Math.abs(dy) > 30) {
// Swipe VERTICAL (atas/bawah)
if (dy > 0) moved = moveDown(); // swipe bawah
else moved = moveUp(); // swipe atas
}
// Logic sama seperti keyboard handler
if (moved) {
isMoving = true;
setTimeout(() => {
const added = addNewTile();
if (!added || !canMove()) {
setTimeout(() => showGameOver(), 300);
}
isMoving = false;
}, 100);
}
}, { passive: true });