Upload files to "/"

This commit is contained in:
5803025048 2025-11-30 22:58:47 -05:00
parent ec3ec011fc
commit b0a527843b
5 changed files with 189 additions and 189 deletions

30
index.php Normal file
View File

@ -0,0 +1,30 @@
<!---------------------------------- index.php ---------------------------------->
<?php
session_start();
$conn = new mysqli("localhost","root","","breakout_db");
if($conn->connect_error){ die("DB Error"); }
?>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Breakout Game</h1>
<div class="menu">
<a href="login.php">Login / Register</a>
<a href="leaderboard.php">Leaderboard</a>
</div>
<canvas id="game" width="480" height="320"></canvas>
<p>Score: <span id="score">0</span></p>
<p>
<select id="diff">
<option value="easy">Easy</option>
<option value="medium">Medium</option>
<option value="hard">Hard</option>
</select>
<button onclick="startGame()">Start</button>
</p>
<script src="game.js"></script>
</body>
</html>

19
leaderboard.php Normal file
View File

@ -0,0 +1,19 @@
<?php
session_start();
$conn = new mysqli("localhost","root","","breakout_db");
$lb = $conn->query("SELECT username, highscore FROM users ORDER BY highscore DESC LIMIT 10");
?>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h2>Leaderboard</h2>
<table>
<?php while($r = $lb->fetch_assoc()){ ?>
<tr><td><?= $r['username'] ?></td><td><?= $r['highscore'] ?></td></tr>
<?php } ?>
</table>
</body>
</html>

49
login.php Normal file
View File

@ -0,0 +1,49 @@
<?php
session_start();
$conn = new mysqli("localhost","root","","breakout_db");
if($conn->connect_error){ die("DB Error"); }
// Register
if(isset($_POST['register'])){
$u = $_POST['user'];
$p = password_hash($_POST['pass'], PASSWORD_DEFAULT);
$conn->query("INSERT INTO users(username,password,highscore) VALUES('$u','$p',0)");
}
// Login
if(isset($_POST['login'])){
$u = $_POST['user'];
$p = $_POST['pass'];
$res = $conn->query("SELECT * FROM users WHERE username='$u'");
if($row = $res->fetch_assoc()){
if(password_verify($p, $row['password'])){
$_SESSION['user'] = $u;
header("Location: index.php");
exit;
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="login-box">
<h2>Login</h2>
<form method="POST">
<input name="user" placeholder="Username" required>
<input name="pass" type="password" placeholder="Password" required>
<button name="login">Login</button>
</form>
<h2>Register</h2>
<form method="POST">
<input name="user" placeholder="Username" required>
<input name="pass" type="password" placeholder="Password" required>
<button name="register">Register</button>
</form>
</div>
</body>
</html>

7
save.php Normal file
View File

@ -0,0 +1,7 @@
<?php
session_start();
$conn = new mysqli("localhost","root","","breakout_db");
$u = $_SESSION['user'];
$s = intval($_GET['score']);
$conn->query("UPDATE users SET highscore = GREATEST(highscore, $s) WHERE username='$u'");
?>

241
script.js
View File

@ -1,189 +1,84 @@
const canvas = document.getElementById('gameCanvas'); let canvas = document.getElementById("game");
const ctx = canvas.getContext('2d'); let ctx = canvas.getContext("2d");
const uiLayer = document.getElementById('ui-layer');
const finalScoreSpan = document.getElementById('final-score');
const inGameScore = document.getElementById('ingame-score');
const highScoreDisplay = document.getElementById('high-score-display');
// Setup UI Flexbox
uiLayer.style.display = 'none';
let score = 0; let score = 0;
let gameRunning = true; let running = false;
let speed = 2; let ball, paddle, bricks, rows, cols, speed;
let blockHeight = 35; let hitSound = new Audio("hit.wav");
let initialWidth = 200; let loseSound = new Audio("lose.wav");
let blocks = [];
let currentBlock = {};
let direction = 1;
let hue = 0;
function initGame() { function startGame(){
score = 0; score = 0;
blocks = []; document.getElementById("score").textContent = score;
speed = 3; running = true;
hue = Math.random() * 360;
inGameScore.innerText = score; let diff = document.getElementById("diff").value;
if(diff === "easy"){ rows = 3; cols = 5; speed = 3; }
if(diff === "medium"){ rows = 4; cols = 7; speed = 4; }
if(diff === "hard"){ rows = 6; cols = 9; speed = 5; }
// Base block paddle = { x:200, w:80, h:10 };
blocks.push({ ball = { x:240, y:200, dx:speed, dy:-speed, r:6 };
x: (canvas.width - initialWidth) / 2, bricks = [];
y: canvas.height - 100,
width: initialWidth, for(let r=0;r<rows;r++){
color: `hsl(${hue}, 100%, 50%)` for(let c=0;c<cols;c++){
bricks.push({ x: c*50+30, y: r*20+30, w:40, h:15, hit:false });
}
}
requestAnimationFrame(loop);
}
function loop(){
if(!running) return;
ctx.clearRect(0,0,480,320);
ctx.fillStyle = "white";
ctx.fillRect(paddle.x, 300, paddle.w, paddle.h);
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI*2);
ctx.fill();
ball.x += ball.dx;
ball.y += ball.dy;
if(ball.x < ball.r || ball.x > 480-ball.r) ball.dx *= -1;
if(ball.y < ball.r) ball.dy *= -1;
if(ball.y > 294 && ball.x > paddle.x && ball.x < paddle.x+paddle.w){
ball.dy *= -1;
hitSound.play();
}
bricks.forEach(b =>{
if(!b.hit && ball.x > b.x && ball.x < b.x+b.w && ball.y > b.y && ball.y < b.y+b.h){
b.hit = true;
ball.dy *= -1;
score += 10;
document.getElementById("score").textContent = score;
hitSound.play();
}
}); });
spawnBlock(); bricks.forEach(b =>{
if(!b.hit){ ctx.fillRect(b.x,b.y,b.w,b.h); }
// Perubahan: Jangan panggil draw() di sini jika ini reset,
// biarkan resetGame yang mengontrol loop
if(gameRunning) draw();
}
function spawnBlock() {
const prevBlock = blocks[blocks.length - 1];
hue += 10;
currentBlock = {
x: 0,
y: prevBlock.y - blockHeight,
width: prevBlock.width,
color: `hsl(${hue}, 100%, 50%)`
};
if (currentBlock.y < 150) {
blocks.forEach(b => b.y += blockHeight);
currentBlock.y += blockHeight;
}
}
function drawBackground() {
ctx.strokeStyle = 'rgba(255, 255, 255, 0.05)';
ctx.lineWidth = 1;
for (let i = 0; i < canvas.width; i += 40) {
ctx.beginPath(); ctx.moveTo(i, 0); ctx.lineTo(i, canvas.height); ctx.stroke();
}
for (let i = 0; i < canvas.height; i += 40) {
ctx.beginPath(); ctx.moveTo(0, i); ctx.lineTo(canvas.width, i); ctx.stroke();
}
}
function draw() {
if (!gameRunning) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBackground();
currentBlock.x += speed * direction;
if (currentBlock.x + currentBlock.width > canvas.width || currentBlock.x < 0) {
direction *= -1;
}
ctx.shadowBlur = 20;
blocks.forEach(b => {
ctx.fillStyle = b.color;
ctx.shadowColor = b.color;
ctx.fillRect(b.x, b.y, b.width, blockHeight);
ctx.fillStyle = 'rgba(255,255,255,0.2)';
ctx.fillRect(b.x, b.y, b.width, 5);
}); });
ctx.fillStyle = currentBlock.color; if(ball.y > 330){
ctx.shadowColor = currentBlock.color; loseSound.play();
ctx.fillRect(currentBlock.x, currentBlock.y, currentBlock.width, blockHeight); running = false;
ctx.fillStyle = 'rgba(255,255,255,0.4)'; saveScore();
ctx.fillRect(currentBlock.x, currentBlock.y, currentBlock.width, 5); alert("Game Over");
ctx.shadowBlur = 0;
requestAnimationFrame(draw);
}
function placeBlock() {
if (!gameRunning) return;
const prevBlock = blocks[blocks.length - 1];
let overlap = currentBlock.width - Math.abs(currentBlock.x - prevBlock.x);
if (overlap <= 0) {
gameOver();
return; return;
} }
if (currentBlock.x < prevBlock.x) { requestAnimationFrame(loop);
currentBlock.width = overlap;
currentBlock.x = prevBlock.x;
} else {
currentBlock.width = overlap;
} }
blocks.push(currentBlock); window.addEventListener("mousemove", e =>{
score++; paddle.x = e.clientX - canvas.offsetLeft - paddle.w/2;
inGameScore.innerText = score;
speed += 0.15;
spawnBlock();
}
function gameOver() {
gameRunning = false;
uiLayer.style.display = 'flex';
finalScoreSpan.innerText = score;
saveScore(score);
}
// --- PERBAIKAN UTAMA ADA DI SINI ---
function resetGame() {
uiLayer.style.display = 'none';
// Matikan gameRunning sementara agar klik tombol tidak terbaca sebagai 'placeBlock'
gameRunning = false;
initGame();
// Beri jeda 300ms. Setelah tombol dilepas, baru game aktif.
setTimeout(() => {
gameRunning = true;
draw(); // Mulai loop animasi
}, 300);
}
// Input Handler yang lebih aman
document.body.onkeydown = (e) => {
if (e.code === 'Space') {
if (gameRunning) {
placeBlock();
} else if (uiLayer.style.display === 'flex') {
// Cegah spasi merestart terlalu cepat
resetGame();
}
}
};
document.body.onclick = (e) => {
// PENTING: Jika yang diklik adalah tombol atau bagian dari UI Layer, JANGAN jalankan game
if (e.target.closest('#ui-layer') || e.target.closest('.btn')) return;
if (gameRunning) placeBlock();
};
function saveScore(newScore) {
const formData = new FormData();
formData.append('score', newScore);
fetch('save_score.php', { method: 'POST', body: formData })
.then(response => response.json())
.then(data => fetchHighScore());
}
function fetchHighScore() {
fetch('save_score.php?action=get')
.then(response => response.json())
.then(data => {
highScoreDisplay.innerText = data.high_score || "0";
}); });
}
// Start pertama kali function saveScore(){
initGame(); fetch("save.php?score="+score);
// Paksa draw pertama kali }
gameRunning = true;
draw();