Upload files to "/"
This commit is contained in:
parent
fd74ce79e8
commit
e3e295e090
@ -7,7 +7,7 @@ if(isset($_POST['register'])){
|
|||||||
$u = $_POST['user'];
|
$u = $_POST['user'];
|
||||||
$p = password_hash($_POST['pass'], PASSWORD_DEFAULT);
|
$p = password_hash($_POST['pass'], PASSWORD_DEFAULT);
|
||||||
$u_safe = $conn->real_escape_string($u);
|
$u_safe = $conn->real_escape_string($u);
|
||||||
$conn->query("INSERT INTO users(username,password,highscore) VALUES('$u_safe','$p',0)");
|
$conn->query("INSERT INTO users(username,password,highscore_easy, highscore_medium, highscore_hard) VALUES('$u_safe','$p',0,0,0)");
|
||||||
if($conn->affected_rows > 0) {
|
if($conn->affected_rows > 0) {
|
||||||
$_SESSION['user'] = $u;
|
$_SESSION['user'] = $u;
|
||||||
header("Location: index.php");
|
header("Location: index.php");
|
||||||
|
|||||||
20
save.php
20
save.php
@ -1,7 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
$conn = new mysqli("localhost","root","","breakout_db");
|
$conn = new mysqli("localhost","root","","breakout_db");
|
||||||
|
|
||||||
|
if(!isset($_SESSION['user']) || !isset($_GET['score']) || !isset($_GET['diff'])) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
$u = $_SESSION['user'];
|
$u = $_SESSION['user'];
|
||||||
$s = intval($_GET['score']);
|
$s = intval($_GET['score']);
|
||||||
$conn->query("UPDATE users SET highscore = GREATEST(highscore, $s) WHERE username='$u'");
|
$diff = $_GET['diff'];
|
||||||
|
|
||||||
|
$column = "";
|
||||||
|
if($diff === 'easy') {
|
||||||
|
$column = "highscore_easy";
|
||||||
|
} elseif ($diff === 'medium') {
|
||||||
|
$column = "highscore_medium";
|
||||||
|
} elseif ($diff === 'hard') {
|
||||||
|
$column = "highscore_hard";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($column != "") {
|
||||||
|
$conn->query("UPDATE users SET $column = GREATEST($column, $s) WHERE username='$u'");
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
89
script.js
89
script.js
@ -3,6 +3,8 @@ let ctx = canvas.getContext("2d");
|
|||||||
let score = 0;
|
let score = 0;
|
||||||
let running = false;
|
let running = false;
|
||||||
let ball, paddle, bricks, rows, cols, speed;
|
let ball, paddle, bricks, rows, cols, speed;
|
||||||
|
let currentDiff = "easy";
|
||||||
|
|
||||||
const brickColors = ["#FF5733", "#33FF57", "#3357FF", "#FF33F5", "#33FFF5", "#F5FF33"];
|
const brickColors = ["#FF5733", "#33FF57", "#3357FF", "#FF33F5", "#33FFF5", "#F5FF33"];
|
||||||
|
|
||||||
let hitSound = new Audio("hit.wav");
|
let hitSound = new Audio("hit.wav");
|
||||||
@ -10,14 +12,12 @@ let loseSound = new Audio("lose.wav");
|
|||||||
let wallSound = new Audio("wall.wav");
|
let wallSound = new Audio("wall.wav");
|
||||||
let winSound = new Audio("win.wav");
|
let winSound = new Audio("win.wav");
|
||||||
|
|
||||||
// Ambil elemen modal baru
|
|
||||||
const gameModal = document.getElementById("gameModal");
|
const gameModal = document.getElementById("gameModal");
|
||||||
const modalTitle = document.getElementById("modalTitle");
|
const modalTitle = document.getElementById("modalTitle");
|
||||||
const modalScore = document.getElementById("modalScore");
|
const modalScore = document.getElementById("modalScore");
|
||||||
const saveScoreBtn = document.getElementById("saveScoreBtn");
|
const saveScoreBtn = document.getElementById("saveScoreBtn");
|
||||||
const playAgainBtn = document.getElementById("playAgainBtn");
|
const playAgainBtn = document.getElementById("playAgainBtn");
|
||||||
|
|
||||||
// Event Listener untuk tombol Play Again di modal
|
|
||||||
if (playAgainBtn) {
|
if (playAgainBtn) {
|
||||||
playAgainBtn.addEventListener('click', () => {
|
playAgainBtn.addEventListener('click', () => {
|
||||||
gameModal.style.display = 'none';
|
gameModal.style.display = 'none';
|
||||||
@ -25,7 +25,6 @@ if (playAgainBtn) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event Listener untuk tombol Save Score di modal (jika user login)
|
|
||||||
if (saveScoreBtn) {
|
if (saveScoreBtn) {
|
||||||
saveScoreBtn.addEventListener('click', () => {
|
saveScoreBtn.addEventListener('click', () => {
|
||||||
saveScore(true);
|
saveScore(true);
|
||||||
@ -47,26 +46,20 @@ function startGame(){
|
|||||||
document.getElementById("score").textContent = score;
|
document.getElementById("score").textContent = score;
|
||||||
running = true;
|
running = true;
|
||||||
|
|
||||||
let diff = document.getElementById("diff").value;
|
// Simpan kesulitan yang dipilih ke variabel global currentDiff
|
||||||
|
let diffInput = document.getElementById("diff").value;
|
||||||
|
currentDiff = diffInput;
|
||||||
|
|
||||||
let initialHealth = 1;
|
let initialHealth = 1;
|
||||||
|
|
||||||
if(diff === "easy"){
|
if(currentDiff === "easy"){
|
||||||
rows = 3;
|
rows = 3; cols = 5; speed = 2; initialHealth = 1;
|
||||||
cols = 5;
|
|
||||||
speed = 2;
|
|
||||||
initialHealth = 1;
|
|
||||||
}
|
}
|
||||||
if(diff === "medium"){
|
if(currentDiff === "medium"){
|
||||||
rows = 4;
|
rows = 4; cols = 7; speed = 4; initialHealth = 3;
|
||||||
cols = 7;
|
|
||||||
speed = 4;
|
|
||||||
initialHealth = 3;
|
|
||||||
}
|
}
|
||||||
if(diff === "hard"){
|
if(currentDiff === "hard"){
|
||||||
rows = 6;
|
rows = 6; cols = 9; speed = 5; initialHealth = 5;
|
||||||
cols = 9;
|
|
||||||
speed = 5;
|
|
||||||
initialHealth = 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
paddle = { x:200, w:80, h:10 };
|
paddle = { x:200, w:80, h:10 };
|
||||||
@ -118,59 +111,41 @@ function update(){
|
|||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
|
|
||||||
// Pantulan Dinding
|
|
||||||
if(ball.x + ball.r > canvas.width || ball.x - ball.r < 0){
|
if(ball.x + ball.r > canvas.width || ball.x - ball.r < 0){
|
||||||
ball.dx *= -1;
|
ball.dx *= -1; lockSpeed();
|
||||||
lockSpeed();
|
wallSound.currentTime = 0; wallSound.play();
|
||||||
wallSound.currentTime = 0;
|
|
||||||
wallSound.play();
|
|
||||||
}
|
}
|
||||||
if(ball.y - ball.r < 0){
|
if(ball.y - ball.r < 0){
|
||||||
ball.dy *= -1;
|
ball.dy *= -1; lockSpeed();
|
||||||
lockSpeed();
|
wallSound.currentTime = 0; wallSound.play();
|
||||||
wallSound.currentTime = 0;
|
|
||||||
wallSound.play();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tabrakan Paddle
|
|
||||||
if(ball.y + ball.r > canvas.height - paddle.h && ball.x > paddle.x && ball.x < paddle.x + paddle.w){
|
if(ball.y + ball.r > canvas.height - paddle.h && ball.x > paddle.x && ball.x < paddle.x + paddle.w){
|
||||||
let deltaX = ball.x - (paddle.x + paddle.w/2);
|
let deltaX = ball.x - (paddle.x + paddle.w/2);
|
||||||
|
|
||||||
let dy_abs = Math.abs(speed) * -1;
|
let dy_abs = Math.abs(speed) * -1;
|
||||||
|
|
||||||
ball.dx = deltaX * 0.15;
|
ball.dx = deltaX * 0.15;
|
||||||
ball.dy = dy_abs;
|
ball.dy = dy_abs;
|
||||||
|
|
||||||
lockSpeed();
|
lockSpeed();
|
||||||
|
wallSound.currentTime = 0; wallSound.play();
|
||||||
wallSound.currentTime = 0;
|
|
||||||
wallSound.play();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tabrakan Brick
|
|
||||||
bricks.forEach(b =>{
|
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){
|
if(!b.hit && ball.x > b.x && ball.x < b.x+b.w && ball.y > b.y && ball.y < b.y+b.h){
|
||||||
|
|
||||||
b.health--;
|
b.health--;
|
||||||
ball.dy *= -1;
|
ball.dy *= -1;
|
||||||
|
|
||||||
lockSpeed();
|
lockSpeed();
|
||||||
|
|
||||||
if (b.health <= 0) {
|
if (b.health <= 0) {
|
||||||
b.hit = true;
|
b.hit = true;
|
||||||
score += 10;
|
score += 10;
|
||||||
winSound.currentTime = 0;
|
winSound.currentTime = 0; winSound.play();
|
||||||
winSound.play();
|
|
||||||
} else {
|
} else {
|
||||||
hitSound.currentTime = 0;
|
hitSound.currentTime = 0; hitSound.play();
|
||||||
hitSound.play();
|
|
||||||
// Perubahan warna berdasarkan sisa health
|
|
||||||
if (b.health === 4) b.color = '#B22222';
|
if (b.health === 4) b.color = '#B22222';
|
||||||
if (b.health === 3) b.color = '#CD853F';
|
if (b.health === 3) b.color = '#CD853F';
|
||||||
if (b.health === 2) b.color = '#FFA07A';
|
if (b.health === 2) b.color = '#FFA07A';
|
||||||
if (b.health === 1) b.color = '#F08080';
|
if (b.health === 1) b.color = '#F08080';
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("score").textContent = score;
|
document.getElementById("score").textContent = score;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -184,43 +159,33 @@ function update(){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cek Kemenangan - Menampilkan Modal
|
|
||||||
if(bricks.every(b => b.hit)){
|
if(bricks.every(b => b.hit)){
|
||||||
winSound.currentTime = 0;
|
winSound.currentTime = 0; winSound.play();
|
||||||
winSound.play();
|
|
||||||
running = false;
|
running = false;
|
||||||
showModal("YOU WIN!", score);
|
showModal("YOU WIN!", score);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cek Game Over - Menampilkan Modal
|
|
||||||
if(ball.y > canvas.height){
|
if(ball.y > canvas.height){
|
||||||
loseSound.currentTime = 0;
|
loseSound.currentTime = 0; loseSound.play();
|
||||||
loseSound.play();
|
|
||||||
running = false;
|
running = false;
|
||||||
showModal("GAME OVER!", score);
|
showModal("GAME OVER!", score);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pengendalian Paddle
|
|
||||||
canvas.addEventListener("mousemove", e =>{
|
canvas.addEventListener("mousemove", e =>{
|
||||||
if (!paddle || !canvas) return;
|
if (!paddle || !canvas) return;
|
||||||
|
|
||||||
const canvasRect = canvas.getBoundingClientRect();
|
const canvasRect = canvas.getBoundingClientRect();
|
||||||
let newX = e.clientX - canvasRect.left - paddle.w/2;
|
let newX = e.clientX - canvasRect.left - paddle.w/2;
|
||||||
|
|
||||||
if(newX < 0) newX = 0;
|
if(newX < 0) newX = 0;
|
||||||
if(newX > canvas.width - paddle.w) newX = canvas.width - paddle.w;
|
if(newX > canvas.width - paddle.w) newX = canvas.width - paddle.w;
|
||||||
|
|
||||||
paddle.x = newX;
|
paddle.x = newX;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fungsi untuk menampilkan modal
|
|
||||||
function showModal(title, finalScore) {
|
function showModal(title, finalScore) {
|
||||||
modalTitle.textContent = title;
|
modalTitle.textContent = title;
|
||||||
modalScore.innerHTML = `Final Score: <b>${finalScore}</b>`;
|
modalScore.innerHTML = `Final Score: <b>${finalScore}</b> <br> (${currentDiff.toUpperCase()})`;
|
||||||
gameModal.style.display = 'flex';
|
gameModal.style.display = 'flex';
|
||||||
|
|
||||||
// Reset tombol save score
|
|
||||||
if (saveScoreBtn) {
|
if (saveScoreBtn) {
|
||||||
saveScoreBtn.disabled = false;
|
saveScoreBtn.disabled = false;
|
||||||
saveScoreBtn.textContent = 'Save Score';
|
saveScoreBtn.textContent = 'Save Score';
|
||||||
@ -234,24 +199,22 @@ function saveScore(fromModal = false){
|
|||||||
|
|
||||||
if (isUserLoggedIn) {
|
if (isUserLoggedIn) {
|
||||||
if (fromModal) {
|
if (fromModal) {
|
||||||
|
|
||||||
if (saveScoreBtn) {
|
if (saveScoreBtn) {
|
||||||
saveScoreBtn.disabled = true;
|
saveScoreBtn.disabled = true;
|
||||||
saveScoreBtn.textContent = 'Saving...';
|
saveScoreBtn.textContent = 'Saving...';
|
||||||
saveScoreBtn.style.opacity = '0.7';
|
saveScoreBtn.style.opacity = '0.7';
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch(`save.php?score=${score}`)
|
// Perubahan: Menambahkan &diff=... ke URL
|
||||||
|
fetch(`save.php?score=${score}&diff=${currentDiff}`)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
console.log("Score saved successfully!");
|
|
||||||
if (saveScoreBtn) {
|
if (saveScoreBtn) {
|
||||||
saveScoreBtn.textContent = 'Saved! ✅';
|
saveScoreBtn.textContent = 'Saved! ✅';
|
||||||
saveScoreBtn.style.background = 'gray';
|
saveScoreBtn.style.background = 'gray';
|
||||||
saveScoreBtn.style.opacity = '1';
|
saveScoreBtn.style.opacity = '1';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error("Failed to save score.");
|
|
||||||
if (saveScoreBtn) {
|
if (saveScoreBtn) {
|
||||||
saveScoreBtn.textContent = 'Failed ❌';
|
saveScoreBtn.textContent = 'Failed ❌';
|
||||||
saveScoreBtn.disabled = false;
|
saveScoreBtn.disabled = false;
|
||||||
@ -267,10 +230,6 @@ function saveScore(fromModal = false){
|
|||||||
saveScoreBtn.style.opacity = '1';
|
saveScoreBtn.style.opacity = '1';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
console.log("Score ready to be saved via modal.");
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
console.log("Score not saved. User is not logged in.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
70
style.css
70
style.css
@ -17,11 +17,18 @@ h1 {
|
|||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
margin-top: 20px;
|
||||||
|
text-shadow: 3px 3px 10px rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
|
||||||
.menu {
|
.menu {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu a {
|
.menu a {
|
||||||
@ -47,6 +54,8 @@ h1 {
|
|||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-container {
|
.game-container {
|
||||||
@ -108,11 +117,6 @@ button:hover {
|
|||||||
box-shadow: 0px 7px 18px rgba(255,76,76,0.55);
|
box-shadow: 0px 7px 18px rgba(255,76,76,0.55);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
h1 { font-size: 2.2rem; }
|
|
||||||
canvas { width: 100%; height: auto; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaderboard-body {
|
.leaderboard-body {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -120,24 +124,40 @@ button:hover {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
.leaderboard-wrapper {
|
||||||
font-size: 2.5rem;
|
display: flex;
|
||||||
margin-top: 20px;
|
flex-wrap: wrap;
|
||||||
text-shadow: 3px 3px 10px rgba(0,0,0,0.4);
|
justify-content: center;
|
||||||
}
|
gap: 20px;
|
||||||
|
|
||||||
.board-container {
|
|
||||||
margin: 25px auto;
|
margin: 25px auto;
|
||||||
width: 95%;
|
width: 95%;
|
||||||
max-width: 650px;
|
max-width: 1200px;
|
||||||
background: rgba(255,255,255,0.10);
|
}
|
||||||
padding: 25px;
|
|
||||||
|
.lb-column {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 300px;
|
||||||
|
background: rgba(255,255,255,0.1);
|
||||||
|
padding: 20px;
|
||||||
border-radius: 18px;
|
border-radius: 18px;
|
||||||
backdrop-filter: blur(12px);
|
backdrop-filter: blur(12px);
|
||||||
border: 1px solid rgba(255,255,255,0.25);
|
border: 1px solid rgba(255,255,255,0.25);
|
||||||
box-shadow: 0px 10px 25px rgba(0,0,0,0.25);
|
box-shadow: 0px 10px 25px rgba(0,0,0,0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lb-column h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
text-shadow: 2px 2px 8px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.easy-title { color: #33FF57; border-bottom: 2px solid #33FF57; display: inline-block; padding-bottom: 5px; }
|
||||||
|
.medium-title { color: #3357FF; border-bottom: 2px solid #3357FF; display: inline-block; padding-bottom: 5px; }
|
||||||
|
.hard-title { color: #FF33F5; border-bottom: 2px solid #FF33F5; display: inline-block; padding-bottom: 5px; }
|
||||||
|
|
||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
@ -170,7 +190,7 @@ tr:hover td {
|
|||||||
|
|
||||||
.back-button {
|
.back-button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-top: 25px;
|
margin: 25px auto;
|
||||||
padding: 10px 22px;
|
padding: 10px 22px;
|
||||||
background: linear-gradient(45deg, #28a745, #21c064);
|
background: linear-gradient(45deg, #28a745, #21c064);
|
||||||
border-radius: 25px;
|
border-radius: 25px;
|
||||||
@ -207,14 +227,8 @@ tr:hover td {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes popup {
|
@keyframes popup {
|
||||||
from {
|
from { opacity: 0; transform: scale(0.85); }
|
||||||
opacity: 0;
|
to { opacity: 1; transform: scale(1); }
|
||||||
transform: scale(0.85);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-box input, .login-box button {
|
.login-box input, .login-box button {
|
||||||
@ -245,6 +259,7 @@ tr:hover td {
|
|||||||
width: 90%;
|
width: 90%;
|
||||||
margin-left: 5%;
|
margin-left: 5%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-modal {
|
.game-modal {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -317,3 +332,10 @@ tr:hover td {
|
|||||||
.leaderboard-link:hover, .back-link:hover {
|
.leaderboard-link:hover, .back-link:hover {
|
||||||
background: rgba(255, 255, 255, 0.15);
|
background: rgba(255, 255, 255, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
h1 { font-size: 2.2rem; }
|
||||||
|
canvas { width: 100%; height: auto; }
|
||||||
|
.leaderboard-wrapper { flex-direction: column; }
|
||||||
|
.lb-column { width: 100%; min-width: auto; }
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user