615 lines
16 KiB
PHP
615 lines
16 KiB
PHP
<<<<<<< HEAD
|
||
<?php
|
||
session_start();
|
||
if (!isset($_SESSION['user'])) {
|
||
header("Location: index.php");
|
||
exit;
|
||
}
|
||
$username = $_SESSION['user'];
|
||
// koneksi db
|
||
$conn = new mysqli("localhost", "root", "", "dodge_game");
|
||
// Ambil skin user dari database
|
||
$q = $conn->query("SELECT skin FROM users WHERE username='$username'");
|
||
$skinColor = $q->fetch_assoc()["skin"];
|
||
// Daftar warna skin
|
||
$skinList = [
|
||
"cyan" => "#00ffff",
|
||
"blue" => "#0066ff",
|
||
"yellow" => "#ffee00",
|
||
"purple" => "#ff55ff",
|
||
"green" => "#33ff55"
|
||
];
|
||
// Warna player yang dipakai
|
||
$playerColor = $skinList[$skinColor];
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>Hindari Block Multi</title>
|
||
<style>
|
||
body {
|
||
font-family: Arial;
|
||
background: url('assets/bg.jpg') no-repeat center center fixed;
|
||
background-size: cover;
|
||
color: white;
|
||
margin: 0;
|
||
display: flex;
|
||
}
|
||
#gameWrapper {
|
||
width: 75%;
|
||
padding: 20px;
|
||
text-align: center;
|
||
}
|
||
#gameArea {
|
||
width: 400px;
|
||
height: 500px;
|
||
background: #222;
|
||
margin: 0 auto;
|
||
position: relative;
|
||
overflow: hidden;
|
||
border-radius: 10px;
|
||
box-shadow: 0 0 10px #000;
|
||
}
|
||
#player {
|
||
width: 40px;
|
||
height: 40px;
|
||
background: <?= $playerColor ?>;
|
||
position: absolute;
|
||
bottom: 10px;
|
||
left: 180px;
|
||
border-radius: 8px;
|
||
}
|
||
.block {
|
||
width: 40px;
|
||
height: 40px;
|
||
background: red;
|
||
position: absolute;
|
||
border-radius: 8px;
|
||
}
|
||
#leaderboard {
|
||
width: 25%;
|
||
padding: 20px;
|
||
background: #111;
|
||
border-left: 2px solid #333;
|
||
height: 100vh;
|
||
}
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
}
|
||
th, td {
|
||
padding: 8px;
|
||
border-bottom: 1px solid #333;
|
||
}
|
||
/* ===== POPUP GAME OVER ===== */
|
||
#gameOverPopup {
|
||
display: none;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: rgba(0,0,0,0.7);
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
.popup-box {
|
||
background: #222;
|
||
padding: 25px;
|
||
border-radius: 10px;
|
||
text-align: center;
|
||
width: 300px;
|
||
box-shadow: 0 0 10px #000;
|
||
}
|
||
.popup-box button {
|
||
margin-top: 15px;
|
||
padding: 10px;
|
||
width: 120px;
|
||
border: none;
|
||
cursor: pointer;
|
||
font-size: 16px;
|
||
border-radius: 6px;
|
||
background: #00d37e;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="gameWrapper">
|
||
<h1>Hindari Block Multi</h1>
|
||
<p>Player: <b><?= $username ?></b></p>
|
||
<div class="score-box">Score: <span id="score">0</span></div>
|
||
<div id="gameArea">
|
||
<div id="player"></div>
|
||
</div>
|
||
<p>Credits: Haekal Adi Rendra & Gerrad</p>
|
||
</div>
|
||
<div id="leaderboard">
|
||
<h2>Leaderboard</h2>
|
||
<table>
|
||
<tr>
|
||
<th>User</th>
|
||
<th>Score</th>
|
||
</tr>
|
||
<?php
|
||
$result = $conn->query("SELECT username, score FROM leaderboard ORDER BY score DESC LIMIT 20");
|
||
while ($row = $result->fetch_assoc()) {
|
||
echo "<tr><td>{$row['username']}</td><td>{$row['score']}</td></tr>";
|
||
}
|
||
?>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- ========= POPUP GAME OVER ========= -->
|
||
<div id="gameOverPopup">
|
||
<div class="popup-box">
|
||
<h2>Game Over</h2>
|
||
<p>Score Kamu: <span id="finalScore"></span></p>
|
||
<button id="btnRestart">New Game</button>
|
||
<button id="btnmenu">Menu</button>
|
||
</div>
|
||
</div>
|
||
|
||
<audio id="soundMove" src="assets/sound/move.wav"></audio>
|
||
<audio id="soundScore" src="assets/sound/score.wav"></audio>
|
||
<audio id="soundGameOver" src="assets/sound/gameover.wav"></audio>
|
||
|
||
<script>
|
||
let currentUser = "<?= $username ?>";
|
||
|
||
// ========= AUDIO =========
|
||
const soundMove = document.getElementById("soundMove");
|
||
const soundScore = document.getElementById("soundScore");
|
||
const soundGameOver = document.getElementById("soundGameOver");
|
||
|
||
// ========= GAME VARIABLES =========
|
||
const player = document.getElementById("player");
|
||
const gameArea = document.getElementById("gameArea");
|
||
let score = 0;
|
||
let gameRunning = true;
|
||
let blockSpeed = 2;
|
||
const maxBlockSpeed = 14;
|
||
let blocks = [];
|
||
|
||
// ========= CREATE MULTIPLE BLOCKS AT ONCE =========
|
||
function spawnBlocks() {
|
||
if (!gameRunning) return;
|
||
|
||
// Tentukan jumlah block yang akan muncul (1–3)
|
||
let blockCount = 1;
|
||
if (score >= 300) blockCount = Math.floor(Math.random() * 2) + 2; // 2–3
|
||
else if (score >= 150) blockCount = Math.floor(Math.random() * 2) + 1; // 1–2
|
||
else if (score >= 50) blockCount = Math.random() < 0.3 ? 2 : 1; // 30% chance 2 block
|
||
// score < 50 → selalu 1
|
||
|
||
const usedPositions = []; // agar tidak tumpang tindih
|
||
|
||
for (let i = 0; i < blockCount; i++) {
|
||
let leftPos;
|
||
let attempts = 0;
|
||
do {
|
||
leftPos = Math.floor(Math.random() * 10) * 40; // grid: 0,40,80,...,360
|
||
attempts++;
|
||
} while (usedPositions.includes(leftPos) && attempts < 20);
|
||
|
||
if (attempts >= 20) continue; // skip jika terlalu sulit cari posisi
|
||
|
||
usedPositions.push(leftPos);
|
||
|
||
let newBlock = document.createElement("div");
|
||
newBlock.classList.add("block");
|
||
newBlock.style.top = "-60px";
|
||
newBlock.style.left = leftPos + "px";
|
||
gameArea.appendChild(newBlock);
|
||
blocks.push(newBlock);
|
||
}
|
||
}
|
||
|
||
// ========= PLAYER MOVEMENT (grid 40px) =========
|
||
document.addEventListener("keydown", e => {
|
||
if (!gameRunning) return;
|
||
let left = parseInt(player.style.left) || 180;
|
||
|
||
if (e.key === "ArrowLeft" && left > 0) {
|
||
player.style.left = (left - 40) + "px";
|
||
soundMove.currentTime = 0;
|
||
soundMove.play();
|
||
}
|
||
if (e.key === "ArrowRight" && left < 360) {
|
||
player.style.left = (left + 40) + "px";
|
||
soundMove.currentTime = 0;
|
||
soundMove.play();
|
||
}
|
||
});
|
||
|
||
// ========= UPDATE SPEED =========
|
||
function updateBlockSpeed() {
|
||
blockSpeed = 2 + Math.floor(score / 18);
|
||
if (blockSpeed > maxBlockSpeed) blockSpeed = maxBlockSpeed;
|
||
}
|
||
|
||
// ========= SPAWN INTERVAL (dinamis) =========
|
||
let spawnDelay = 1400;
|
||
|
||
function startSpawner() {
|
||
spawnBlocks(); // spawn pertama
|
||
setInterval(() => {
|
||
if (gameRunning) {
|
||
spawnBlocks();
|
||
|
||
// Percepat spawn sesuai score
|
||
if (score >= 400) spawnDelay = 400;
|
||
else if (score >= 300) spawnDelay = 500;
|
||
else if (score >= 200) spawnDelay = 600;
|
||
else if (score >= 100) spawnDelay = 800;
|
||
else if (score >= 50) spawnDelay = 1000;
|
||
}
|
||
}, spawnDelay);
|
||
}
|
||
|
||
startSpawner();
|
||
|
||
// Spawn tambahan di awal agar langsung ramai
|
||
setTimeout(() => spawnBlocks(), 800);
|
||
setTimeout(() => spawnBlocks(), 1600);
|
||
|
||
// ========= GAME LOOP =========
|
||
function fall() {
|
||
if (!gameRunning) return;
|
||
|
||
const playerLeft = parseInt(player.style.left) || 180;
|
||
|
||
blocks = blocks.filter(block => {
|
||
let top = parseInt(block.style.top || -60);
|
||
let left = parseInt(block.style.left);
|
||
|
||
top += blockSpeed;
|
||
block.style.top = top + "px";
|
||
|
||
// Collision
|
||
if (top >= 450 && top <= 490 && Math.abs(left - playerLeft) < 40) {
|
||
gameRunning = false;
|
||
soundGameOver.play();
|
||
saveScore(score);
|
||
showGameOver(score);
|
||
return false;
|
||
}
|
||
|
||
// Lolos bawah
|
||
if (top > 550) {
|
||
score += 10;
|
||
document.getElementById("score").innerText = score;
|
||
updateBlockSpeed();
|
||
soundScore.currentTime = 0;
|
||
soundScore.play();
|
||
block.remove();
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
});
|
||
|
||
requestAnimationFrame(fall);
|
||
}
|
||
fall();
|
||
|
||
// ========= SAVE SCORE =========
|
||
function saveScore(finalScore) {
|
||
fetch("save_score.php", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||
body: "username=" + encodeURIComponent(currentUser) + "&score=" + finalScore
|
||
});
|
||
}
|
||
|
||
// ========= GAME OVER POPUP =========
|
||
const popup = document.getElementById("gameOverPopup");
|
||
const finalScoreText = document.getElementById("finalScore");
|
||
|
||
document.getElementById("btnRestart").onclick = () => location.reload();
|
||
document.getElementById("btnmenu").onclick = () => location.href = "menu.php";
|
||
|
||
function showGameOver(finalScore) {
|
||
finalScoreText.textContent = finalScore;
|
||
popup.style.display = "flex";
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|
||
=======
|
||
<?php
|
||
session_start();
|
||
if (!isset($_SESSION['user'])) {
|
||
header("Location: index.php");
|
||
exit;
|
||
}
|
||
|
||
$username = $_SESSION['user'];
|
||
|
||
// koneksi db
|
||
$conn = new mysqli("localhost", "root", "", "dodge_game");
|
||
// Ambil skin user dari database
|
||
$q = $conn->query("SELECT skin FROM users WHERE username='$username'");
|
||
$skinColor = $q->fetch_assoc()["skin"];
|
||
|
||
// Daftar warna skin
|
||
$skinList = [
|
||
"cyan" => "#00ffff",
|
||
"blue" => "#0066ff",
|
||
"yellow" => "#ffee00",
|
||
"purple" => "#ff55ff",
|
||
"green" => "#33ff55"
|
||
];
|
||
|
||
// Warna player yang dipakai
|
||
$playerColor = $skinList[$skinColor];
|
||
|
||
?>
|
||
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>Hindari Block</title>
|
||
<style>
|
||
body {
|
||
font-family: Arial;
|
||
background: url('assets/bg.jpg') no-repeat center center fixed;
|
||
background-size: cover;
|
||
color: white;
|
||
margin: 0;
|
||
display: flex;
|
||
}
|
||
|
||
#gameWrapper {
|
||
width: 75%;
|
||
padding: 20px;
|
||
text-align: center;
|
||
}
|
||
|
||
#gameArea {
|
||
width: 400px;
|
||
height: 500px;
|
||
background: #222;
|
||
margin: 0 auto;
|
||
position: relative;
|
||
overflow: hidden;
|
||
border-radius: 10px;
|
||
box-shadow: 0 0 10px #000;
|
||
}
|
||
|
||
#player {
|
||
width: 40px;
|
||
height: 40px;
|
||
background: <?= $playerColor ?>;
|
||
position: absolute;
|
||
bottom: 10px;
|
||
left: 180px;
|
||
border-radius: 8px;
|
||
}
|
||
|
||
|
||
#block {
|
||
width: 40px;
|
||
height: 40px;
|
||
background: red;
|
||
position: absolute;
|
||
top: -40px;
|
||
left: 180px;
|
||
border-radius: 8px;
|
||
}
|
||
|
||
#leaderboard {
|
||
width: 25%;
|
||
padding: 20px;
|
||
background: #111;
|
||
border-left: 2px solid #333;
|
||
height: 100vh;
|
||
}
|
||
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
}
|
||
|
||
th, td {
|
||
padding: 8px;
|
||
border-bottom: 1px solid #333;
|
||
}
|
||
|
||
/* ===== POPUP GAME OVER ===== */
|
||
#gameOverPopup {
|
||
display: none;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: rgba(0,0,0,0.7);
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.popup-box {
|
||
background: #222;
|
||
padding: 25px;
|
||
border-radius: 10px;
|
||
text-align: center;
|
||
width: 300px;
|
||
box-shadow: 0 0 10px #000;
|
||
}
|
||
|
||
.popup-box button {
|
||
margin-top: 15px;
|
||
padding: 10px;
|
||
width: 120px;
|
||
border: none;
|
||
cursor: pointer;
|
||
font-size: 16px;
|
||
border-radius: 6px;
|
||
}
|
||
|
||
#btnRestart {
|
||
background: #00d37e;
|
||
}
|
||
|
||
#btnLmenu {
|
||
background: #00d37e;
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<div id="gameWrapper">
|
||
<h1>Hindari Block</h1>
|
||
<p>Player: <b><?= $username ?></b></p>
|
||
<div class="score-box">Score: <span id="score">0</span></div>
|
||
|
||
<div id="gameArea">
|
||
<div id="player"></div>
|
||
<div id="block"></div>
|
||
</div>
|
||
<p>Credits: Haekal Adi Rendra & Gerrad</p>
|
||
</div>
|
||
|
||
<div id="leaderboard">
|
||
<h2>Leaderboard</h2>
|
||
<table>
|
||
<tr>
|
||
<th>User</th>
|
||
<th>Score</th>
|
||
</tr>
|
||
|
||
<?php
|
||
$result = $conn->query("SELECT username, score FROM leaderboard ORDER BY score DESC LIMIT 20");
|
||
while ($row = $result->fetch_assoc()) {
|
||
echo "<tr><td>{$row['username']}</td><td>{$row['score']}</td></tr>";
|
||
}
|
||
?>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- ========= POPUP GAME OVER ========= -->
|
||
<div id="gameOverPopup">
|
||
<div class="popup-box">
|
||
<h2>Game Over</h2>
|
||
<p>Score Kamu: <span id="finalScore"></span></p>
|
||
|
||
<button id="btnRestart">New Game</button>
|
||
<button id="btnmenu">Menu</button>
|
||
</div>
|
||
</div>
|
||
<audio id="soundMove" src="assets/sound/move.wav"></audio>
|
||
<audio id="soundScore" src="assets/sound/score.wav"></audio>
|
||
<audio id="soundGameOver" src="assets/sound/gameover.wav"></audio>
|
||
|
||
<script>
|
||
let currentUser = "<?= $username ?>";
|
||
</script>
|
||
|
||
<script>
|
||
// ========= GAME SCRIPT ==========
|
||
const player = document.getElementById("player");
|
||
const block = document.getElementById("block");
|
||
let score = 0;
|
||
let gameRunning = true;
|
||
|
||
document.addEventListener("keydown", e => {
|
||
if (!gameRunning) return;
|
||
|
||
let left = parseInt(window.getComputedStyle(player).getPropertyValue("left"));
|
||
|
||
if (e.key === "ArrowLeft" && left > 0) {
|
||
player.style.left = (left - 20) + "px";
|
||
soundMove.currentTime = 0;
|
||
soundMove.play();
|
||
}
|
||
|
||
if (e.key === "ArrowRight" && left < 360) {
|
||
player.style.left = (left + 20) + "px";
|
||
soundMove.currentTime = 0;
|
||
soundMove.play();
|
||
}
|
||
});
|
||
|
||
|
||
let blockSpeed = 5; // kecepatan awal block
|
||
|
||
function fall() {
|
||
if (!gameRunning) return;
|
||
|
||
let blockTop = parseInt(window.getComputedStyle(block).getPropertyValue("top"));
|
||
let blockLeft = parseInt(window.getComputedStyle(block).getPropertyValue("left"));
|
||
let playerLeft = parseInt(window.getComputedStyle(player).getPropertyValue("left"));
|
||
|
||
// TABRAKAN
|
||
if (blockTop > 450 && Math.abs(blockLeft - playerLeft) < 40) {
|
||
gameRunning = false;
|
||
soundGameOver.play();
|
||
saveScore(score);
|
||
showGameOver(score);
|
||
return;
|
||
}
|
||
|
||
// Jika block sudah jatuh ke bawah
|
||
if (blockTop > 500) {
|
||
block.style.top = "-40px";
|
||
block.style.left = Math.floor(Math.random() * 360) + "px";
|
||
score++;
|
||
document.getElementById("score").innerText = score;
|
||
|
||
// ======== TINGKATKAN KECEPATAN BLOCK BERDASARKAN SCORE ========
|
||
if (score === 15) blockSpeed = 7;
|
||
if (score === 25) blockSpeed = 8;
|
||
if (score === 35) blockSpeed = 10;
|
||
if (score === 45) blockSpeed = 12;
|
||
if (score === 60) blockSpeed = 14;
|
||
if (score === 80) blockSpeed = 16;
|
||
if (score === 100) blockSpeed = 18;
|
||
|
||
soundScore.currentTime = 0;
|
||
soundScore.play();
|
||
} else {
|
||
block.style.top = (blockTop + blockSpeed) + "px";
|
||
}
|
||
|
||
requestAnimationFrame(fall);
|
||
}
|
||
fall();
|
||
|
||
|
||
|
||
// ================== SIMPAN SKOR KE SERVER ==================
|
||
function saveScore(finalScore) {
|
||
fetch("save_score.php", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||
body: "username=" + currentUser + "&score=" + finalScore
|
||
});
|
||
}
|
||
|
||
|
||
// ================== POPUP GAME OVER ==================
|
||
const popup = document.getElementById("gameOverPopup");
|
||
const finalScoreText = document.getElementById("finalScore");
|
||
const btnRestart = document.getElementById("btnRestart");
|
||
const btnmenu = document.getElementById("btnmenu");
|
||
|
||
function showGameOver(finalScore) {
|
||
finalScoreText.textContent = finalScore;
|
||
popup.style.display = "flex";
|
||
}
|
||
|
||
btnRestart.onclick = () => {
|
||
window.location.reload();
|
||
};
|
||
|
||
btnmenu.onclick = () => {
|
||
window.location.href = "menu.php";
|
||
};
|
||
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|
||
>>>>>>> 720425e3f38951553731cb9aae9a4c9a34f6c2b4
|