ga jadi ga isa konek

This commit is contained in:
JERRY F 2025-12-13 19:00:10 +07:00
parent e8975da670
commit da8b69c174
3 changed files with 338 additions and 236 deletions

View File

@ -1,4 +1,4 @@
//bagian tempat main ama buat generate game 2d // //bagian tempat main ama buat generate game 2d
var canvas = document.getElementById("game"); var canvas = document.getElementById("game");
var content = canvas.getContext("2d"); var content = canvas.getContext("2d");
const Text = document.getElementById("text"); const Text = document.getElementById("text");
@ -25,9 +25,9 @@ KepalaKeKanan.src = "image/KepalaHorizontalKanan.png";
var KepalaKeAtas = new Image(); var KepalaKeAtas = new Image();
KepalaKeAtas.src = "image/KepalaVertikalAtas.png"; KepalaKeAtas.src = "image/KepalaVertikalAtas.png";
var KepalaKeKiri = new Image(); var KepalaKeKiri = new Image();
KepalaKeKiri.src = "image/KepalaVertikalBawah.png"; KepalaKeKiri.src = "image/KepalaVertikalBawah.png"; // Asumsi ini adalah Kepala ke KIRI
var KepalaKeBawah = new Image(); var KepalaKeBawah = new Image();
KepalaKeBawah.src = "image/KepalaHorizontalKiri.png"; KepalaKeBawah.src = "image/KepalaHorizontalKiri.png"; // Asumsi ini adalah Kepala ke BAWAH
// ↑ kepala ular // ↑ kepala ular
var BadanHori = new Image(); var BadanHori = new Image();
@ -50,291 +50,324 @@ RandomizeApel();
//mastiin gambar external generate dulu sebelum game start //mastiin gambar external generate dulu sebelum game start
KepalaKeKanan.onload = function () { KepalaKeKanan.onload = function () {
function gameLoop() {} // Memastikan gambar termuat, meskipun fungsi ini tidak melakukan apa-apa selain deklarasi
function gameLoop() {}
}; };
//ngatur biar game ga langsung jalan //ngatur biar game ga langsung jalan
function StartingGame(menantang) { function StartingGame(menantang) {
ModeH = menantang; ModeH = menantang;
persiapan.style.display = "none"; persiapan.style.display = "none";
if (ModeH) { if (ModeH) {
RandomSpawnWall(); RandomSpawnWall();
} else { } else {
Tembok = []; Tembok = [];
} }
GameStart = true; GameStart = true;
} }
//buat ngatur batu spwan apa ga nanti //buat ngatur batu spwan apa ga nanti
document.getElementById("mode-normal").addEventListener("click", function () { document.getElementById("mode-normal").addEventListener("click", function () {
StartingGame(false); StartingGame(false);
}); });
document.getElementById("mode-tambahan").addEventListener("click", function () { document.getElementById("mode-tambahan").addEventListener("click", function () {
StartingGame(true); StartingGame(true);
}); });
//play again pas gameover //play again pas gameover
function resetGame() { function resetGame() {
Ular.x = 528; Ular.x = 528;
Ular.y = 240; Ular.y = 240;
Ular.cells = []; Ular.cells = [];
Ular.maxCells = 4; Ular.maxCells = 4;
Ular.dx = grid; Ular.dx = grid;
Ular.dy = 0; Ular.dy = 0;
Tembok = []; Tembok = [];
RandomizeApel(); RandomizeApel();
UpdateScore(0); UpdateScore(0);
ModeH = false; ModeH = false;
GameStart = false; // Penting: Jangan set GameStart=false di sini jika ingin memulai ulang game loop
// Kita set GameStart=false saat game over, lalu di sini kita persiapkan UI
} }
//ngatur tombol pas gameover kemana abis di klik //ngatur tombol pas gameover kemana abis di klik
PlayAgain.addEventListener("click", function () { PlayAgain.addEventListener("click", function () {
UpDead.style.display = "none"; UpDead.style.display = "none";
resetGame(); resetGame();
persiapan.style.display = "flex"; persiapan.style.display = "flex";
}); });
Udahan.addEventListener("click", function () { Udahan.addEventListener("click", function () {
UpDead.style.display = "none"; UpDead.style.display = "none";
resetGame(); resetGame();
// Opsional: Redirect ke halaman lain
// window.location.href = 'leaderboard.php';
}); });
//gameover terus ngatur ular ke setting awal //gameover terus ngatur ular ke setting awal
function gameLoop() { function gameLoop() {
if (!GameStart) { if (!GameStart) {
requestAnimationFrame(gameLoop); requestAnimationFrame(gameLoop);
return; return;
} }
ClearCanvas(); ClearCanvas();
Movement(); Movement();
IntiGame(); IntiGame();
requestAnimationFrame(gameLoop); requestAnimationFrame(gameLoop);
} }
//random spawn Apel //random spawn Apel
function RandomizeApel() { function RandomizeApel() {
var pembataslebar = Math.floor(canvas.width / grid); var pembataslebar = Math.floor(canvas.width / grid);
var pembatastinggi = Math.floor(canvas.height / grid); var pembatastinggi = Math.floor(canvas.height / grid);
Apel.x = Math.floor(Math.random() * pembataslebar) * grid;
Apel.y = Math.floor(Math.random() * pembatastinggi) * grid; do {
Apel.x = Math.floor(Math.random() * pembataslebar) * grid;
Apel.y = Math.floor(Math.random() * pembatastinggi) * grid;
// Pastikan Apel tidak spawn di atas ular
var isOverlapSnake = Ular.cells.some(cell => cell.x === Apel.x && cell.y === Apel.y);
// Pastikan Apel tidak spawn di atas tembok
var isOverlapWall = Tembok.some(bata => bata.x === Apel.x && bata.y === Apel.y);
} while (isOverlapSnake || isOverlapWall);
} }
//random spawn tembok //random spawn tembok
function RandomSpawnWall() { function RandomSpawnWall() {
var TembokX, TembokY; var TembokX, TembokY;
var kosong; var kosong;
var pembataslebar = Math.floor(canvas.width / grid); var pembataslebar = Math.floor(canvas.width / grid);
var pembatastinggi = Math.floor(canvas.height / grid); var pembatastinggi = Math.floor(canvas.height / grid);
//create tembok //create tembok
do { do {
kosong = true; kosong = true;
TembokX = Math.floor(Math.random() * pembataslebar) * grid; TembokX = Math.floor(Math.random() * pembataslebar) * grid;
TembokY = Math.floor(Math.random() * pembatastinggi) * grid; TembokY = Math.floor(Math.random() * pembatastinggi) * grid;
//cek untuk posisi yang mau di kasih tembok ada/tidak ada ularnya // cek untuk posisi yang mau di kasih tembok ada/tidak ada ularnya
for (var i = 0; i < Ular.cells.length; i++) { for (var i = 0; i < Ular.cells.length; i++) {
if (Ular.cells[i].x === TembokX && Ular.cells[i].y === TembokY) { // Hindari spawn di sekitar kepala ular (misal 5 kotak pertama)
kosong = false; if (Math.abs(Ular.cells[i].x - TembokX) <= grid * 5 && Math.abs(Ular.cells[i].y - TembokY) <= grid * 5) {
break; kosong = false;
} break;
} }
}
//tidak memperbolehkan tembok spawn sama dengan apel // tidak memperbolehkan tembok spawn sama dengan apel
if (TembokX === Apel.x && TembokY === Apel.y) { if (TembokX === Apel.x && TembokY === Apel.y) {
kosong = false; kosong = false;
} }
for (var i = 0; i < Tembok.length; i++) { // Cek agar tembok tidak menumpuk
if (Tembok[i].x === TembokX && Tembok[i].y === TembokY) { for (var i = 0; i < Tembok.length; i++) {
kosong = false; if (Tembok[i].x === TembokX && Tembok[i].y === TembokY) {
break; kosong = false;
} break;
} }
} while (kosong === false); }
Tembok.push({ x: TembokX, y: TembokY }); } while (kosong === false);
Tembok.push({ x: TembokX, y: TembokY });
} }
//nambah tembok tiap score kelipatan ... berapa enaknya ya? 😁 //nambah tembok tiap score kelipatan
function PenambahanTembok() { function PenambahanTembok() {
if (ModeH) { if (ModeH) {
if (Tembok.length < Math.floor(score / 2)) { // Tambah tembok setiap 2 skor, tapi jangan melebihi batas (misal 15 tembok)
RandomSpawnWall(); if (score > 0 && score % 2 === 0 && Tembok.length < 15 && Tembok.length < score / 2) {
RandomSpawnWall();
}
} }
}
} }
//set dan update score //set dan update score
function UpdateScore(amount) { function UpdateScore(amount) {
score = amount > 0 ? score + amount : 0; score = amount > 0 ? score + amount : 0;
highscore = score > highscore ? score : highscore; // Highscore hanya di update jika skor > highscore yang TERCATAT LOKAL.
Text.innerHTML = // Highscore dari database biasanya diambil saat inisialisasi.
"Score: " + score + "<br>Highscore: " + highscore + "<br>Speed: " + speed; highscore = score > highscore ? score : highscore;
PenambahanTembok(); Text.innerHTML =
"Score: " + score + "<br>Highscore: " + highscore + "<br>Speed: " + speed;
PenambahanTembok();
} }
//tampilin gameover //tampilin gameover
function GameOver() { function GameOver() {
GameStart = false; GameStart = false;
ClearCanvas(); ClearCanvas();
const modePermainan = ModeH ? "Tambahan" : "Normal"; const modePermainan = ModeH ? "Tambahan" : "Normal";
if (score >= 0) {
kirimSkorKeServer(score, modePermainan);
}
// TAMPILKAN POP-UP GAME OVER // Kirim skor ke server hanya jika skor lebih besar dari 0 (atau sesuai kriteria)
ScoreMain.innerHTML = "Score: " + score; if (score > 0) {
UpDead.style.display = "flex"; kirimSkorKeServer(score, modePermainan);
}
// TAMPILKAN POP-UP GAME OVER
ScoreMain.innerHTML = "Score: " + score;
UpDead.style.display = "flex";
} }
//reset isi canvas doang //reset isi canvas doang
function ClearCanvas() { function ClearCanvas() {
content.clearRect(0, 0, canvas.width, canvas.height); content.clearRect(0, 0, canvas.width, canvas.height);
} }
//bagian utama: //bagian utama:
//ular makan dan mati pas ketemu badannya //ular makan dan mati pas ketemu badannya
function IntiGame() { function IntiGame() {
//buat gambarnya bisa keluar // buat gambarnya bisa keluar
content.drawImage(ApelImage, Apel.x, Apel.y, grid, grid); 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) { // Gambar Tembok
if (index === 0) { Tembok.forEach(function (bata) {
// Logika Pemilihan Gambar Kepala Ular content.drawImage(TembokImage, bata.x, bata.y, grid, grid);
var posisiKepalaImage; });
if (Ular.dx === grid) {
// KANAN
posisiKepalaImage = KepalaKeKanan;
} else if (Ular.dx === -grid) {
// KIRI
posisiKepalaImage = KepalaKeKiri;
} else if (Ular.dy === -grid) {
// ATAS
posisiKepalaImage = KepalaKeBawah;
} else if (Ular.dy === grid) {
// BAWAH
posisiKepalaImage = KepalaKeAtas;
} else {
// Default, misalnya saat game baru mulai (dx=grid, dy=0, atau default awal)
posisiKepalaImage = KepalaKeKanan;
}
content.drawImage(posisiKepalaImage, cell.x, cell.y, grid, grid); // Gambar Ular
} else { Ular.cells.forEach(function (cell, index) {
content.drawImage(BadanHori, cell.x, cell.y, grid, grid); if (index === 0) {
} // Logika Pemilihan Gambar Kepala Ular
}); var posisiKepalaImage;
if (Ular.dx === grid) { // KANAN
//bagian generate ular posisiKepalaImage = KepalaKeKanan;
Ular.cells.forEach(function (cell, index) { } else if (Ular.dx === -grid) { // KIRI
if (index === 0) { posisiKepalaImage = KepalaKeKiri;
content.drawImage(KepalaKeKanan, cell.x, cell.y, grid, grid); } else if (Ular.dy === -grid) { // ATAS
} else { posisiKepalaImage = KepalaKeAtas; // Perlu dicek, di atas Anda menamakannya KepalaKeBawah?
content.drawImage(BadanHori, cell.x, cell.y, grid, grid); } else if (Ular.dy === grid) { // BAWAH
} posisiKepalaImage = KepalaKeBawah; // Perlu dicek, di atas Anda menamakannya KepalaKeAtas?
} else {
//buat pas ular makan Apel posisiKepalaImage = KepalaKeKanan;
if (cell.x === Apel.x && cell.y === Apel.y) { }
Ular.maxCells += 1; content.drawImage(posisiKepalaImage, cell.x, cell.y, grid, grid);
UpdateScore(1); } else {
RandomizeApel(); // Logika sederhana untuk badan: selalu horizontal
} // Catatan: untuk badan vertikal/belokan, perlu logika tambahan, tapi kita ikuti kode asli Anda.
content.drawImage(BadanHori, cell.x, cell.y, grid, grid);
//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 // buat pas ular makan Apel (Deteksi tabrakan kepala vs Apel)
for (var i = index + 1; i < Ular.cells.length; i++) if (index === 0 && cell.x === Apel.x && cell.y === Apel.y) {
if (cell.x === Ular.cells[i].x && cell.y === Ular.cells[i].y) GameOver(); Ular.maxCells += 1;
}); UpdateScore(1);
RandomizeApel();
}
// tabrak tembok = mati (Hanya kepala yang dicek)
if (index === 0) {
Tembok.forEach(function (bata) {
if (cell.x === bata.x && cell.y === bata.y) {
GameOver();
}
});
}
// buat pas ular mati kena badan sendiri (Hanya kepala vs sisa badan)
if (index === 0) {
for (var i = 1; i < Ular.cells.length; i++) { // Mulai dari index 1 (badan)
if (cell.x === Ular.cells[i].x && cell.y === Ular.cells[i].y) {
GameOver();
}
}
}
});
} }
//update teks pada speed kalau score update //update teks pada speed kalau score update
function Movement() { function Movement() {
if (++count < speed) return; if (++count < speed) return;
if (ArahUlar > 0) ArahUlar--; if (ArahUlar > 0) ArahUlar--;
count = 0; count = 0;
Ular.x += Ular.dx;
Ular.y += Ular.dy; // Pindahkan kepala
if ( Ular.x += Ular.dx;
Ular.x < 0 || Ular.y += Ular.dy;
Ular.x >= canvas.width ||
Ular.y < 0 || // Cek batas layar
Ular.y >= canvas.height if (
) Ular.x < 0 ||
GameOver(); Ular.x >= canvas.width ||
Ular.cells.unshift({ x: Ular.x, y: Ular.y }); Ular.y < 0 ||
if (Ular.cells.length > Ular.maxCells) Ular.cells.pop(); Ular.y >= canvas.height
)
GameOver();
// Tambahkan posisi baru ke sel pertama (Kepala)
Ular.cells.unshift({ x: Ular.x, y: Ular.y });
// Hapus sel terakhir (Ekor)
if (Ular.cells.length > Ular.maxCells) Ular.cells.pop();
} }
//input keyboard //input keyboard
function InputKeyboard() { function InputKeyboard() {
document.addEventListener("keydown", function (e) { document.addEventListener("keydown", function (e) {
if (!GameStart) return; if (!GameStart) return;
//jalan buat ular // Key A, D (Kiri/Kanan)
if ( if (
ArahUlar == 0 && ArahUlar == 0 &&
((e.code == "KeyA" && Ular.dx === 0) || ((e.code == "KeyA" && Ular.dx === 0) ||
(e.code == "KeyD" && Ular.dx === 0)) (e.code == "KeyD" && Ular.dx === 0))
) { ) {
ArahUlar = 1; ArahUlar = 1;
Ular.dx = e.code === "KeyA" ? -grid : grid; Ular.dx = e.code === "KeyA" ? -grid : grid;
Ular.dy = 0; Ular.dy = 0;
} else if ( }
ArahUlar == 0 && // Key W, S (Atas/Bawah)
((e.code === "KeyW" && Ular.dy === 0) || else if (
(e.code == "KeyS" && Ular.dy === 0)) ArahUlar == 0 &&
) { ((e.code === "KeyW" && Ular.dy === 0) ||
ArahUlar = 1; (e.code == "KeyS" && Ular.dy === 0))
Ular.dy = e.code == "KeyW" ? -grid : grid; ) {
Ular.dx = 0; ArahUlar = 1;
} else if ( Ular.dy = e.code == "KeyW" ? -grid : grid;
ArahUlar == 0 && Ular.dx = 0;
((e.code === "ArrowUp" && Ular.dy === 0) || }
(e.code == "ArrowDown" && Ular.dy === 0)) // Arrow Up, Down
) { else if (
ArahUlar = 1; ArahUlar == 0 &&
Ular.dy = e.code == "ArrowUp" ? -grid : grid; ((e.code === "ArrowUp" && Ular.dy === 0) ||
Ular.dx = 0; (e.code == "ArrowDown" && Ular.dy === 0))
} else if ( ) {
ArahUlar == 0 && ArahUlar = 1;
((e.code === "ArrowLeft" && Ular.dx === 0) || Ular.dy = e.code == "ArrowUp" ? -grid : grid;
(e.code == "ArrowRight" && Ular.dx === 0)) Ular.dx = 0;
) { }
ArahUlar = 1; // Arrow Left, Right
Ular.dx = e.code == "ArrowLeft" ? -grid : grid; else if (
Ular.dy = 0; 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") // Key E (Cepat/Kurangi speed), Key Q (Lambat/Tambah speed)
speed = if (e.code === "KeyE" || e.code == "KeyQ")
e.code == "KeyE" && speed > 2 speed =
? speed - 1 e.code == "KeyE" && speed > 2
: e.code == "KeyQ" && speed < 30 ? speed - 1
? speed + 1 : e.code == "KeyQ" && speed < 30
: speed; ? speed + 1
}); : speed;
});
} }
function kirimSkorKeServer(skor, modePermainan) { function kirimSkorKeServer(skor, modePermainan) {
console.log(`Mengirim skor ${skor} (Mode: ${modePermainan}) ke server...`); console.log(`Mengirim skor ${skor} (Mode: ${modePermainan}) ke server...`);
// Ganti 'score.php' sesuai dengan path di server Anda
fetch('score.php', { fetch('score.php', {
method: 'POST', method: 'POST',
headers: { headers: {
@ -347,20 +380,28 @@ function kirimSkorKeServer(skor, modePermainan) {
}) })
.then(response => { .then(response => {
if (!response.ok) { if (!response.ok) {
return response.json().then(error => { throw new Error(error.message || 'Gagal menyimpan skor'); }); return response.json().then(error => { throw new Error(error.message || 'Gagal menyimpan skor'); });
} }
return response.json(); return response.json();
}) })
.then(data => { .then(data => {
if (data.status === 'success') { if (data.status === 'success') {
console.log('✅ Berhasil:', data.message); console.log('✅ Berhasil:', data.message);
// Opsional: Perbarui highscore lokal dengan skor yang baru jika ini highscore
if (data.message.includes('Highscore baru')) {
highscore = skor;
UpdateScore(0); // Update tampilan score/highscore
}
} else { } else {
console.error('❌ Error Server:', data.message); console.error('❌ Error Server:', data.message);
} }
}) })
.catch((error) => { .catch((error) => {
console.error('⚠️ Error Jaringan atau Proses:', error.message); console.error('⚠️ Error Jaringan atau Proses:', error.message);
// Tampilkan pesan error ke user jika perlu
// alert("Gagal terhubung ke server skor. Pastikan Anda sudah login.");
}); });
} }
InputKeyboard(); InputKeyboard();
gameLoop(); gameLoop();

View File

@ -1,6 +1,6 @@
<?php <?php
session_start(); session_start();
require_once "koneksi.php"; require_once "koneksi.php"; // Menggunakan koneksi MySQLi
if (isset($_SESSION['username'])) { if (isset($_SESSION['username'])) {
$nama = $_SESSION['username']; $nama = $_SESSION['username'];
@ -10,7 +10,9 @@ if (isset($_SESSION['username'])) {
$score = 0; $score = 0;
// 1. Ambil Skor User yang Login (Untuk Tampilan Individual, jika diperlukan)
if (!empty($nama)) { if (!empty($nama)) {
// ⚠️ Perlu DITINGKATKAN ke prepared statement untuk keamanan
$getScore = "SELECT score FROM users WHERE username = '$nama'"; $getScore = "SELECT score FROM users WHERE username = '$nama'";
$resultMe = mysqli_query($koneksi, $getScore); $resultMe = mysqli_query($koneksi, $getScore);
@ -20,32 +22,63 @@ if (!empty($nama)) {
} }
} }
// 2. Ambil 10 Skor Tertinggi
$sql = "SELECT username, score FROM users ORDER BY score DESC LIMIT 10"; $sql = "SELECT username, score FROM users ORDER BY score DESC LIMIT 10";
$result = mysqli_query($koneksi, $sql); $result = mysqli_query($koneksi, $sql);
$leaderboard = []; $leaderboard = [];
if($result) { if($result) {
// Ambil semua hasil
$leaderboard = mysqli_fetch_all($result, MYSQLI_ASSOC); $leaderboard = mysqli_fetch_all($result, MYSQLI_ASSOC);
} }
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="id"> <html lang="id">
<style> <style>
body { body {
background: linear-gradient(to bottom right, #A3D438, #004D40); background: linear-gradient(to bottom right, #A3D438, #004D40);
height: 568px; height: 100vh; /* Menggunakan vh agar mencakup seluruh tinggi layar */
display: flex;
flex-direction: column;
align-items: center;
padding-top: 50px;
color: white;
font-family: sans-serif;
}
table {
border-collapse: collapse;
width: 80%;
max-width: 600px;
margin-top: 20px;
background-color: rgba(0, 0, 0, 0.4);
}
th, td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
th {
background-color: #004D40;
color: white;
text-transform: uppercase;
}
tr:nth-child(even) {
background-color: rgba(255, 255, 255, 0.1);
} }
</style> </style>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Leaderboard</title> <title>Leaderboard</title>
<link rel="stylesheet" href="">
<link rel="stylesheet" href="">
</head> </head>
<body> <body>
<h1>🥇 Leaderboard Top 10 🥈</h1>
<?php if (!empty($nama)): ?>
<p style="font-size: 1.2em;">Skor Tertinggi Anda (<?php echo htmlspecialchars($nama); ?>): <strong><?php echo $score; ?> PTS</strong></p>
<?php else: ?>
<p>Silakan <a href="login.php" style="color: yellow;">login</a> untuk melihat skor Anda.</p>
<?php endif; ?>
<table> <table>
<thead> <thead>
<tr> <tr>
@ -64,9 +97,7 @@ if($result) {
<tr> <tr>
<td><?php echo $peringkat; ?></td> <td><?php echo $peringkat; ?></td>
<td><?php echo htmlspecialchars($pemain['username']); ?></td> <td><?php echo htmlspecialchars($pemain['username']); ?></td>
<td><?php echo $pemain['score']; ?> PTS</td> <td><?php echo $pemain['score']; ?> PTS</td>
</tr> </tr>
<?php <?php
@ -75,7 +106,6 @@ if($result) {
} else { } else {
echo '<tr><td colspan="3" style="text-align: center;">Belum ada Pemain</td></tr>'; echo '<tr><td colspan="3" style="text-align: center;">Belum ada Pemain</td></tr>';
} }
?> ?>
</tbody> </tbody>

View File

@ -1,4 +1,5 @@
<?php <?php
session_start();
require_once 'koneksi.php'; require_once 'koneksi.php';
header('Content-Type: application/json'); header('Content-Type: application/json');
@ -9,7 +10,7 @@ if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
exit; exit;
} }
if (!isset($_SESSION['id_user'])) { if (!isset($_SESSION['id_user']) && !isset($_SESSION['username'])) {
http_response_code(401); http_response_code(401);
echo json_encode(['status' => 'error', 'message' => 'Anda harus login untuk menyimpan skor.']); echo json_encode(['status' => 'error', 'message' => 'Anda harus login untuk menyimpan skor.']);
exit; exit;
@ -17,9 +18,7 @@ if (!isset($_SESSION['id_user'])) {
$input = json_decode(file_get_contents('php://input'), true); $input = json_decode(file_get_contents('php://input'), true);
$user_id = $_SESSION['id_user'];
$final_score = (int)($input['score'] ?? 0); $final_score = (int)($input['score'] ?? 0);
$game_mode = $input['mode'] ?? 'Normal';
if ($final_score <= 0) { if ($final_score <= 0) {
http_response_code(400); http_response_code(400);
@ -27,24 +26,56 @@ if ($final_score <= 0) {
exit; exit;
} }
try { $user_id = null;
$sql = "INSERT INTO scores (id_user, score_value, mode) VALUES (:id_user, :score_value, :mode)"; if (isset($_SESSION['id_user'])) {
$stmt = $pdo->prepare($sql); $user_id = $_SESSION['id_user'];
} elseif (isset($_SESSION['username'])) {
$stmt->execute([ $username = $_SESSION['username'];
':id_user' => $user_id,
':score_value' => $final_score,
':mode' => $game_mode
]);
echo json_encode([ $getID_sql = "SELECT id_user FROM users WHERE username = '$username'";
'status' => 'success', $result_id = mysqli_query($koneksi, $getID_sql);
'message' => 'Skor berhasil disimpan.',
'skor_terkirim' => $final_score
]);
} catch (\PDOException $e) { if ($result_id && mysqli_num_rows($result_id) > 0) {
$row = mysqli_fetch_assoc($result_id);
$user_id = $row['id_user'];
}
}
if (!$user_id) {
http_response_code(401);
echo json_encode(['status' => 'error', 'message' => 'ID pengguna tidak ditemukan.']);
exit;
}
$sql = "UPDATE users SET score = ? WHERE id_user = ? AND score < ?";
if ($stmt = mysqli_prepare($koneksi, $sql)) {
mysqli_stmt_bind_param($stmt, "iii", $final_score, $user_id, $final_score);
$exec = mysqli_stmt_execute($stmt);
if ($exec) {
$rows_affected = mysqli_stmt_affected_rows($stmt);
if ($rows_affected > 0) {
$message = 'Skor berhasil diperbarui. Ini adalah Highscore baru!';
} else {
$message = 'Skor berhasil dikirim, tetapi skor tidak lebih tinggi dari Highscore sebelumnya.';
}
echo json_encode([
'status' => 'success',
'message' => $message,
'skor_terkirim' => $final_score
]);
} else {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Gagal menjalankan kueri update: ' . mysqli_stmt_error($stmt)]);
}
mysqli_stmt_close($stmt);
} else {
http_response_code(500); http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Terjadi kesalahan server saat menyimpan data.']); echo json_encode(['status' => 'error', 'message' => 'Gagal mempersiapkan statement: ' . mysqli_error($koneksi)]);
} }
?> ?>