fix lobby and auths
This commit is contained in:
parent
15b7803bc1
commit
5b85a054c9
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.html
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 94 KiB |
@ -1,317 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Hit & Run</title>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;800&family=Playfair+Display:wght@600&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--bg: #071827;
|
||||
--table: #0b2a2f;
|
||||
--felt: #0e3b33;
|
||||
--accent: #f6c64f;
|
||||
--muted: #8fb3b0;
|
||||
--glass: rgba(255, 255, 255, 0.04);
|
||||
--card: #ffffff;
|
||||
--shadow: 0 10px 30px rgba(2, 6, 23, 0.6);
|
||||
--radius: 14px;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Montserrat', system-ui, sans-serif;
|
||||
background: linear-gradient(180deg, var(--bg) 0%, #03212b 100%);
|
||||
color: #e6f7f2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.menu-wrap {
|
||||
width: 100%;
|
||||
max-width: 1100px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 420px;
|
||||
gap: 28px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.table-card {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(255, 255, 255, 0.02),
|
||||
rgba(255, 255, 255, 0.01)
|
||||
);
|
||||
border-radius: 18px;
|
||||
padding: 28px;
|
||||
box-shadow: var(--shadow);
|
||||
border: 1px solid rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.table-stage {
|
||||
background: var(--table);
|
||||
border-radius: 12px;
|
||||
padding: 28px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.table-top {
|
||||
background: radial-gradient(
|
||||
circle at 30% 20%,
|
||||
rgba(255, 255, 255, 0.02),
|
||||
transparent 30%
|
||||
),
|
||||
linear-gradient(180deg, rgba(255, 255, 255, 0.01), transparent);
|
||||
border-radius: 10px;
|
||||
padding: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.table-name {
|
||||
font-family: 'Playfair Display';
|
||||
font-size: 28px;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.felt {
|
||||
background: linear-gradient(180deg, var(--felt), #0b3f32);
|
||||
width: 100%;
|
||||
height: 180px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-stack {
|
||||
position: absolute;
|
||||
left: 28px;
|
||||
top: 40px;
|
||||
transform: rotate(-12deg);
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 92px;
|
||||
height: 128px;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
box-shadow: 0 6px 20px rgba(2, 6, 23, 0.6);
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.card.small {
|
||||
width: 72px;
|
||||
height: 96px;
|
||||
}
|
||||
|
||||
.chip-stack {
|
||||
position: absolute;
|
||||
right: 32px;
|
||||
bottom: 22px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.chip {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(180deg, #ffdd7a, #d4a018);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 800;
|
||||
color: #002;
|
||||
box-shadow: 0 6px 18px rgba(2, 6, 23, 0.5);
|
||||
}
|
||||
|
||||
.menu-box {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(255, 255, 255, 0.02),
|
||||
rgba(255, 255, 255, 0.01)
|
||||
);
|
||||
border-radius: 12px;
|
||||
padding: 22px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 14px 20px;
|
||||
border-radius: 12px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
border: none;
|
||||
box-shadow: 0 6px 18px rgba(2, 6, 23, 0.5);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(180deg, var(--accent), #e3b33b);
|
||||
color: #052426;
|
||||
}
|
||||
|
||||
.btn-ghost {
|
||||
background: transparent;
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.stat {
|
||||
background: var(--glass);
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
min-width: 120px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(2, 6, 23, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: 0.18s;
|
||||
}
|
||||
|
||||
.modal.open {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.modal-card {
|
||||
background: linear-gradient(180deg, #06222b, #0b2b2f);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
width: 420px;
|
||||
}
|
||||
|
||||
@media (max-width: 880px) {
|
||||
.menu-wrap {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="menu-wrap">
|
||||
<div class="table-card">
|
||||
<div class="table-stage">
|
||||
<div class="table-top">
|
||||
<div class="table-name">Hit & Run • Hit or you Lose.</div>
|
||||
|
||||
<div class="felt">
|
||||
<div class="card-stack">
|
||||
<div class="card small"
|
||||
style="
|
||||
transform: rotate(-6deg);
|
||||
background-image: url('Ace\ Spade.png');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
">
|
||||
</div>
|
||||
|
||||
<div class="card"
|
||||
style="
|
||||
transform: translateY(-28px) rotate(-4deg);
|
||||
background-image: url('King\ Hearts.jpg');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="chip-stack">
|
||||
<div class="chip">100</div>
|
||||
<div class="chip" style="width: 46px; height: 46px; font-size: 12px">
|
||||
25
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<aside class="menu-box">
|
||||
<div class="player-profile" style="display:flex; align-items:center; gap:14px; margin-bottom:20px; background:rgba(255,255,255,0.04); padding:14px; border-radius:14px; border:1px solid rgba(255,255,255,0.06); box-shadow:0 8px 24px rgba(2,6,23,0.45)">
|
||||
<div class="avatar" style="width:58px; height:58px; border-radius:50%; background:linear-gradient(180deg,#0e3b33,#0b2a2f); display:flex; align-items:center; justify-content:center; font-size:22px; font-weight:800; color:var(--accent); border:2px solid rgba(246,198,79,0.4); box-shadow:0 6px 14px rgba(0,0,0,0.5)">P</div>
|
||||
<div style="display:flex; flex-direction:column; line-height:1.25">
|
||||
<div style="font-weight:800; font-size:17px">Pemain Utama</div>
|
||||
<div style="font-size:13px; color:var(--muted)">Saldo: <span style="color:var(--accent); font-weight:700">1,250</span></div>
|
||||
<div style="font-size:12px; color:var(--muted)">Status: Masih Pemula Banghh....</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="title">Selamat Datang, Player</div>
|
||||
<div class="subtitle">
|
||||
Dalam permainan Hit & Run. Satu kartu bisa menyelamatkanmu... atau menjatuhkanmu Siap berjudi dengan nasib?
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary" id="playBtn">▶️ MAINKAN</button>
|
||||
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const playBtn = document.getElementById('playBtn');
|
||||
|
||||
playBtn.addEventListener('click', () => {
|
||||
alert('Memulai permainan...');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 95 KiB |
53
Login.html
53
Login.html
@ -1,53 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Hit or Run — Login</title>
|
||||
<style>
|
||||
body{
|
||||
margin:0; font-family:Inter, sans-serif; background:#071827;
|
||||
display:flex; align-items:center; justify-content:center; min-height:100vh;
|
||||
color:white;
|
||||
}
|
||||
.card{
|
||||
background:rgba(255,255,255,0.05); padding:28px; border-radius:16px;
|
||||
width:320px; box-shadow:0 8px 30px rgba(0,0,0,0.5);
|
||||
backdrop-filter:blur(8px);
|
||||
}
|
||||
h2{margin-top:0; text-align:center}
|
||||
label{display:block; margin:10px 0 4px; font-size:14px}
|
||||
input{
|
||||
width:100%; padding:10px; border-radius:8px; border:0; margin-bottom:10px;
|
||||
background:#ffffff12; color:white;
|
||||
}
|
||||
button{
|
||||
width:100%; padding:10px; border-radius:8px; border:0; cursor:pointer;
|
||||
background:linear-gradient(90deg,#ffd54a); color:black; font-weight:600;
|
||||
margin-top:10px;
|
||||
}
|
||||
.note{text-align:center; margin-top:10px; font-size:14px}
|
||||
a{color:#4ade80; text-decoration:none}
|
||||
.logo{
|
||||
text-align:center; margin-bottom:12px; font-size:100px;
|
||||
filter:drop-shadow(0 0 8px #00000088);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="logo">🂡</div>
|
||||
<h2>Login — Hit or Run</h2>
|
||||
|
||||
<label>Username</label>
|
||||
<input type="text" placeholder="Masukkan username" />
|
||||
|
||||
<label>Password</label>
|
||||
<input type="password" placeholder="Masukkan password" />
|
||||
|
||||
<button>Login</button>
|
||||
|
||||
<div class="note">Belum punya akun? <a href="regis.html">Register</a></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
48
Regis.html
48
Regis.html
@ -1,48 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Hit or Run — Register</title>
|
||||
<style>
|
||||
body{
|
||||
margin:0; font-family:Inter, sans-serif; background:#071827;
|
||||
display:flex; align-items:center; justify-content:center; min-height:100vh;
|
||||
color:white;
|
||||
}
|
||||
.card{
|
||||
background:rgba(255,255,255,0.05); padding:28px; border-radius:16px;
|
||||
width:320px; box-shadow:0 8px 30px rgba(0,0,0,0.5);
|
||||
backdrop-filter:blur(8px);
|
||||
}
|
||||
h2{margin-top:0; text-align:center}
|
||||
label{display:block; margin:10px 0 4px; font-size:14px}
|
||||
input{
|
||||
width:100%; padding:10px; border-radius:8px; border:0; margin-bottom:10px;
|
||||
background:#ffffff12; color:white;
|
||||
}
|
||||
button{
|
||||
width:100%; padding:10px; border-radius:8px; border:0; cursor:pointer;
|
||||
background:linear-gradient(90deg,#ffd54a); color:black; font-weight:600;
|
||||
margin-top:10px;
|
||||
}
|
||||
.note{text-align:center; margin-top:10px; font-size:14px}
|
||||
a{color:#4ade80; text-decoration:none}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<h2>Register — Hit or Run</h2>
|
||||
|
||||
<label>Username</label>
|
||||
<input type="text" placeholder="Masukkan username" />
|
||||
|
||||
<label>Password</label>
|
||||
<input type="password" placeholder="Masukkan password" />
|
||||
|
||||
<button onclick="window.location.href='login.html'">Daftar</button>
|
||||
|
||||
<div class="note">Sudah punya akun? <a href="login.html">Login</a></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
12
dump.txt
12
dump.txt
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
require "../includes/config.php";
|
||||
|
||||
if (!isset($_SESSION["user_id"])) {
|
||||
header("Location: login.php");
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<h2>Welcome <?php echo $_SESSION["username"]; ?>!</h2>
|
||||
|
||||
<a href="logout.php">Logout</a>
|
||||
789
ingame.html
789
ingame.html
@ -1,789 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>Hit or Run — Final</title>
|
||||
<style>
|
||||
:root{
|
||||
--card-w:110px;
|
||||
--card-h:154px;
|
||||
/* Posisi Deck Baru (di Kanan, agak ke atas) */
|
||||
--deck-x: 800px; /* Jarak dari kiri stage */
|
||||
--deck-y: 100px; /* Jarak dari atas stage */
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
body{
|
||||
margin:0;
|
||||
min-height:100vh;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
font-family:Inter,system-ui,Arial;
|
||||
background:#071827
|
||||
}
|
||||
|
||||
.stage{
|
||||
width:960px;
|
||||
height:540px;
|
||||
border-radius:12px;
|
||||
overflow:hidden;
|
||||
position:relative;
|
||||
box-shadow:0 18px 50px rgba(0,0,0,.6)
|
||||
}
|
||||
|
||||
.bg{
|
||||
position:absolute;
|
||||
inset:0;
|
||||
background:#153f28
|
||||
}
|
||||
|
||||
.overlay{
|
||||
position:absolute;
|
||||
inset:0;background:linear-gradient(180deg, rgba(11,31,20,.45), rgba(8,24,16,.65));
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
padding:18px
|
||||
}
|
||||
|
||||
.header{
|
||||
color:#dff6e9;
|
||||
font-weight:700;
|
||||
display:flex;
|
||||
justify-content:space-between
|
||||
}
|
||||
|
||||
.table-area{
|
||||
flex:1;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
position:relative
|
||||
}
|
||||
|
||||
/* DECK BARU (Dipindah ke Kanan Dealer) */
|
||||
.deck {
|
||||
position: absolute;
|
||||
/* MENGGUNAKAN POSISI BARU */
|
||||
left: var(--deck-x);
|
||||
top: var(--deck-y);
|
||||
transform: none; /* Dihapus karena sudah ditentukan oleh --deck-x */
|
||||
width: 82px;
|
||||
height: 120px;
|
||||
border-radius: 10px;
|
||||
background: #113625;
|
||||
box-shadow: 0 0 0 2px #0d291c inset, 0 10px 20px rgba(0,0,0,0.55);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #b9e4d0;
|
||||
font-weight: 900;
|
||||
font-size: 14px;
|
||||
letter-spacing: 2px;
|
||||
z-index: 500;
|
||||
}
|
||||
.deck::before,
|
||||
.deck::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 82px;
|
||||
height: 120px;
|
||||
border-radius: 10px;
|
||||
background: #113625;
|
||||
box-shadow: 0 0 0 2px #0d291c inset;
|
||||
}
|
||||
.deck::before { top: -3px; left: -3px; opacity: 0.9; }
|
||||
.deck::after { top: -6px; left: -6px; opacity: 0.8; }
|
||||
|
||||
/* PLAYER */
|
||||
.player-zone{position:absolute;left:50%;bottom:18px;transform:translateX(-50%);width:78%;display:flex;flex-direction:column;align-items:center}
|
||||
.cards-wrapper{position:relative;width:580px;height:170px}
|
||||
|
||||
/* DEALER ZONE */
|
||||
.dealer-zone{
|
||||
position:absolute;
|
||||
left:50%;
|
||||
top:18px;
|
||||
transform:translateX(-50%);
|
||||
width:78%;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
color:#dff6e9;
|
||||
font-weight:700
|
||||
}
|
||||
.dealer-cards{position:relative;width:580px;height:170px}
|
||||
|
||||
/* WRAPPER KARTU */
|
||||
.card-wrapper {
|
||||
position: absolute;
|
||||
width: var(--card-w);
|
||||
height: var(--card-h);
|
||||
transition: transform .4s cubic-bezier(.68,-0.55,.27,1.55);
|
||||
transform-origin: center center;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
/* CARDS (Base Card) */
|
||||
.card{
|
||||
width:var(--card-w);
|
||||
height:var(--card-h);
|
||||
border-radius:10px;
|
||||
background:#fff;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
justify-content:space-between;
|
||||
padding:10px;
|
||||
font-weight:800;
|
||||
box-shadow:0 10px 22px rgba(0,0,0,.45);
|
||||
position:absolute;
|
||||
transition: transform .4s cubic-bezier(.68,-0.55,.27,1.55),
|
||||
opacity .3s ease,
|
||||
filter .3s ease;
|
||||
backface-visibility:hidden;
|
||||
transform-origin:center center;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/* Efek bayangan saat kartu sedang terbang */
|
||||
.card.is-moving {
|
||||
filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.4));
|
||||
}
|
||||
|
||||
/* Warna Teks Merah untuk suit ♥ dan ♦ */
|
||||
.card.red{
|
||||
color:#c42b2b
|
||||
}
|
||||
|
||||
.card .corner{font-size:18px}
|
||||
.card .center{font-size:40px;display:flex;align-items:center;justify-content:center}
|
||||
|
||||
/* Punggung kartu dealer (Kartu tertutup) */
|
||||
.back-card{
|
||||
background:#122f21;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
font-size:20px;
|
||||
color:#bddfcf;
|
||||
letter-spacing:4px;
|
||||
font-weight:900;
|
||||
border-radius:10px;
|
||||
}
|
||||
|
||||
.controls{display:flex;gap:12px;margin-top:8px}
|
||||
button{background:#0f5436;color:#e6fff2;border:0;padding:10px 16px;border-radius:8px;cursor:pointer;font-weight:700}
|
||||
button:disabled{background:#2d2d2d;opacity:.5;cursor:not-allowed}
|
||||
|
||||
/* Input styling */
|
||||
#modalBetInput {
|
||||
background: #e6fff2;
|
||||
color: #0b2b18;
|
||||
}
|
||||
|
||||
/* END SCREEN */
|
||||
.end-screen {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0,0,0,0.7);
|
||||
backdrop-filter: blur(6px);
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
color: white;
|
||||
font-weight: 800;
|
||||
font-size: 48px;
|
||||
letter-spacing: 2px;
|
||||
text-align: center;
|
||||
z-index: 999;
|
||||
}
|
||||
.end-screen button {
|
||||
margin-top: 22px;
|
||||
font-size: 20px;
|
||||
padding: 12px 26px;
|
||||
border: 0;
|
||||
border-radius: 10px;
|
||||
background: #18a56d;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
}
|
||||
.end-screen button:hover { background: #1ccf86; }
|
||||
|
||||
|
||||
/* BETTING SCREEN (MODAL) */
|
||||
.betting-screen {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0,0,0,0.6);
|
||||
backdrop-filter: blur(4px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
z-index: 900;
|
||||
}
|
||||
.betting-panel {
|
||||
background: #153f28;
|
||||
padding: 30px 40px;
|
||||
border-radius: 15px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.8);
|
||||
text-align: center;
|
||||
min-width: 300px;
|
||||
}
|
||||
.betting-panel h2 {
|
||||
margin-top: 0;
|
||||
font-size: 24px;
|
||||
color: #e6fff2;
|
||||
}
|
||||
.betting-panel button {
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
font-size: 18px;
|
||||
}
|
||||
.betting-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.bet-input-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.bet-input-group label {
|
||||
margin-bottom: 8px;
|
||||
font-size: 18px;
|
||||
}
|
||||
.bet-input-group input {
|
||||
padding: 8px;
|
||||
font-size: 18px;
|
||||
width: 100px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #0f5436;
|
||||
text-align: center;
|
||||
}
|
||||
.bet-error {
|
||||
min-height: 20px;
|
||||
color: #ff9999;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="stage" id="stage">
|
||||
<div class="bg"></div>
|
||||
<div class="overlay">
|
||||
|
||||
<div class="header">
|
||||
<div>Your Total Card: <strong id="playerTotalUI">0</strong></div>
|
||||
<div id="status">PLACE YOUR BET</div>
|
||||
</div>
|
||||
|
||||
<div id="deck" class="deck" aria-hidden="true">DECK</div>
|
||||
|
||||
<div class="table-area">
|
||||
|
||||
<div class="dealer-zone" aria-live="polite">
|
||||
<div class="dealer-label">DEALER</div>
|
||||
<div class="dealer-cards" id="dealerWrapper" aria-hidden="false"></div>
|
||||
<div class="dealer-label">Total Dealer: <span id="dealerTotalUI">0</span></div>
|
||||
</div>
|
||||
|
||||
<div class="player-zone">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;width:100%;color:#dff6e9;font-weight:700;margin-bottom:8px">
|
||||
<div>BALANCE: <span id="balanceUI">5000</span></div>
|
||||
<div>CURRENT BET: <span id="currentBetUI">0</span></div>
|
||||
</div>
|
||||
|
||||
<div class="cards-wrapper" id="cardsWrapper" aria-live="polite"></div>
|
||||
|
||||
<div class="controls">
|
||||
<button id="stand" disabled>STAND</button>
|
||||
<button id="hit" disabled>HIT</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="betting-screen" id="bettingScreen" role="dialog" aria-modal="true">
|
||||
<div class="betting-panel">
|
||||
<h2>PLACE YOUR BET</h2>
|
||||
<div class="betting-info">
|
||||
<div>Balance: $<span id="modalBalanceUI">5000</span></div>
|
||||
<div>Min Bet: $10</div>
|
||||
</div>
|
||||
<div class="bet-input-group">
|
||||
<label for="modalBetInput">Bet:</label>
|
||||
<input type="number" id="modalBetInput" min="10" max="5000" value="100">
|
||||
</div>
|
||||
<div class="bet-error" id="modalBetError"></div>
|
||||
<button id="modalDealBtn">DEAL</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="end-screen" id="endScreen" role="dialog" aria-modal="true">
|
||||
<div id="endMessage">RESULT</div>
|
||||
<button id="playAgainBtn">PLAY AGAIN</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ---------- game state ---------- */
|
||||
const ranks = ['A','2','3','4','5','6','7','8','9','10','J','Q','K'];
|
||||
const suits = ['♠','♥','♦','♣'];
|
||||
|
||||
const cardsWrapper = document.getElementById('cardsWrapper');
|
||||
const dealerWrapper = document.getElementById('dealerWrapper');
|
||||
const deckEl = document.getElementById('deck');
|
||||
|
||||
const hitBtn = document.getElementById('hit');
|
||||
const standBtn = document.getElementById('stand');
|
||||
const endScreen = document.getElementById('endScreen');
|
||||
const endMessage = document.getElementById('endMessage');
|
||||
const playAgainBtn = document.getElementById('playAgainBtn');
|
||||
|
||||
// UI Betting Utama
|
||||
const balanceUI = document.getElementById('balanceUI');
|
||||
const currentBetUI = document.getElementById('currentBetUI');
|
||||
|
||||
// UI Betting Modal
|
||||
const bettingScreen = document.getElementById('bettingScreen');
|
||||
const modalBalanceUI = document.getElementById('modalBalanceUI');
|
||||
const modalBetInput = document.getElementById('modalBetInput');
|
||||
const modalBetError = document.getElementById('modalBetError');
|
||||
const modalDealBtn = document.getElementById('modalDealBtn');
|
||||
|
||||
|
||||
let balance = 5000;
|
||||
let currentBet = 0;
|
||||
let gamePhase = 'BETTING';
|
||||
|
||||
|
||||
let playerCards = [];
|
||||
let dealerCards = [];
|
||||
let playerEls = [];
|
||||
let dealerEls = [];
|
||||
|
||||
/* store all hidden dealer cards and their back elements */
|
||||
let dealerHiddenCards = [];
|
||||
let dealerHiddenEls = [];
|
||||
|
||||
|
||||
/* ---------- helpers ---------- */
|
||||
function randomCard(){
|
||||
const r = ranks[Math.floor(Math.random()*ranks.length)];
|
||||
const s = suits[Math.floor(Math.random()*suits.length)];
|
||||
return {rank:r, suit:s, color:(s==='♥'||s==='♦')?'red':'black'};
|
||||
}
|
||||
|
||||
// Mengembalikan elemen CARD (Wajah)
|
||||
function createCardEl(card){
|
||||
const el = document.createElement('div');
|
||||
el.className = 'card' + (card.color==='red' ? ' red' : '');
|
||||
el.innerHTML = `
|
||||
<div class="corner">${card.rank}</div>
|
||||
<div class="center">${card.suit}</div>
|
||||
<div class="corner" style="transform:rotate(180deg)">${card.rank}</div>
|
||||
`;
|
||||
return el;
|
||||
}
|
||||
|
||||
// Mengembalikan elemen Punggung Kartu
|
||||
function createBackCardEl(){
|
||||
const el = document.createElement('div');
|
||||
el.className = 'card back-card';
|
||||
el.innerText = 'HIT';
|
||||
return el;
|
||||
}
|
||||
|
||||
// Fungsi pembungkus untuk menciptakan elemen kartu (front/back) di dalam wrapper (card-wrapper)
|
||||
function wrapCardInContainer(cardEl, isDealer = false){
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'card-wrapper';
|
||||
|
||||
if (!isDealer) {
|
||||
wrapper.style.perspective = '1000px';
|
||||
}
|
||||
|
||||
wrapper.appendChild(cardEl);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
function calc(cards){
|
||||
let total=0, ace=0;
|
||||
for(const c of cards){
|
||||
if(c.rank==='A'){ total+=11; ace++; }
|
||||
else if(['J','Q','K'].includes(c.rank)) total+=10;
|
||||
else total+=Number(c.rank);
|
||||
}
|
||||
while(total>21 && ace>0){ total-=10; ace--; }
|
||||
return total;
|
||||
}
|
||||
|
||||
/* ---------- UI updates ---------- */
|
||||
function updateTotals(){
|
||||
document.getElementById('playerTotalUI').innerText = calc(playerCards);
|
||||
|
||||
const hiddenExists = dealerHiddenEls.length > 0;
|
||||
if(hiddenExists){
|
||||
document.getElementById('dealerTotalUI').innerText = '??';
|
||||
} else {
|
||||
document.getElementById('dealerTotalUI').innerText = calc(dealerCards);
|
||||
}
|
||||
}
|
||||
|
||||
/* layout overlap */
|
||||
function layoutOverlap(list, wrapper){
|
||||
const isDealer = (wrapper === dealerWrapper);
|
||||
|
||||
const cardW_base = 110;
|
||||
const cardH_base = 154;
|
||||
|
||||
const cardW = cardW_base;
|
||||
const cardH = cardH_base;
|
||||
|
||||
const overlap = 28;
|
||||
const count = list.length;
|
||||
|
||||
const totalWidth = cardW + Math.max(0, count-1)*overlap;
|
||||
|
||||
const startX = (wrapper.clientWidth - totalWidth)/2;
|
||||
|
||||
list.forEach((el, i)=>{
|
||||
const x = startX + i*overlap;
|
||||
|
||||
let y = (wrapper.clientHeight - cardH) / 2;
|
||||
|
||||
if (isDealer) {
|
||||
y += 0;
|
||||
}
|
||||
|
||||
el.style.transform = `translate3d(${x}px, ${y}px, 0)`;
|
||||
el.style.zIndex = 100 + i;
|
||||
});
|
||||
}
|
||||
|
||||
// FUNGSI ANIMASI BARU
|
||||
function animateFromDeck(cardWrapper, isInitial = true){
|
||||
const deckRect = deckEl.getBoundingClientRect();
|
||||
const stageRect = document.getElementById('stage').getBoundingClientRect();
|
||||
|
||||
// Perbaikan: Menggunakan offsetLeft dan offsetTop karena Deck sekarang absolute terhadap stage
|
||||
const startX = deckEl.offsetLeft;
|
||||
const startY = deckEl.offsetTop;
|
||||
|
||||
// Ambil posisi target dari transform yang sudah dihitung layoutOverlap
|
||||
const targetTransformMatch = cardWrapper.style.transform.match(/translate3d\((.*?)px,\s*(.*?)px/);
|
||||
const targetX = parseFloat(targetTransformMatch[1]);
|
||||
const targetY = parseFloat(targetTransformMatch[2]);
|
||||
|
||||
// Set posisi awal (dari deck, dengan scale dan rotasi)
|
||||
cardWrapper.style.transition = 'none'; // Matikan transisi untuk penempatan awal
|
||||
cardWrapper.style.transform = `translate3d(${startX}px, ${startY}px, 0) scale(0.4)`;
|
||||
|
||||
// Tambahkan kelas is-moving untuk efek bayangan
|
||||
cardWrapper.querySelector('.card').classList.add('is-moving');
|
||||
|
||||
// Jeda kecil, lalu aktifkan transisi
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
cardWrapper.style.transition = ''; // Aktifkan semua transisi
|
||||
|
||||
// Target posisi akhir
|
||||
cardWrapper.style.transform = `translate3d(${targetX}px, ${targetY}px, 0) scale(1)`;
|
||||
|
||||
// Rotasi acak untuk efek kartu 'terbang' lebih realistis
|
||||
// Karena deck ada di kanan, rotasi Z acak ke arah berlawanan
|
||||
const rotZ = (Math.random() - 1.0) * 12; // Rotasi Z negatif
|
||||
const rotX = isInitial ? 0 : (Math.random() - 0.5) * 10;
|
||||
|
||||
cardWrapper.querySelector('.card').style.transition = 'transform .4s cubic-bezier(.68,-0.55,.27,1.55), filter .3s ease';
|
||||
cardWrapper.querySelector('.card').style.transform = `rotateZ(${rotZ}deg) rotateX(${rotX}deg)`;
|
||||
|
||||
setTimeout(() => {
|
||||
// Hapus kelas moving setelah transisi selesai
|
||||
cardWrapper.querySelector('.card').classList.remove('is-moving');
|
||||
cardWrapper.querySelector('.card').style.transform = `rotateZ(0deg) rotateX(0deg)`; // Kembali ke posisi normal
|
||||
cardWrapper.querySelector('.card').style.transition = ''; // Kembali ke transisi default CSS
|
||||
}, 400); // Durasi transisi
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* ---------- dealing ---------- */
|
||||
function dealPlayer(){
|
||||
const card = randomCard();
|
||||
playerCards.push(card);
|
||||
|
||||
const cardEl = createCardEl(card);
|
||||
const wrapper = wrapCardInContainer(cardEl, false);
|
||||
cardsWrapper.appendChild(wrapper);
|
||||
playerEls.push(wrapper);
|
||||
|
||||
layoutOverlap(playerEls, cardsWrapper);
|
||||
animateFromDeck(wrapper);
|
||||
|
||||
updateTotals();
|
||||
}
|
||||
|
||||
function dealDealer(faceDown=false){
|
||||
let card, wrapper;
|
||||
|
||||
if(faceDown){
|
||||
card = randomCard();
|
||||
dealerCards.push(card);
|
||||
|
||||
const backEl = createBackCardEl();
|
||||
wrapper = wrapCardInContainer(backEl, true);
|
||||
dealerWrapper.appendChild(wrapper);
|
||||
dealerEls.push(wrapper);
|
||||
|
||||
dealerHiddenCards.push(card);
|
||||
dealerHiddenEls.push(wrapper);
|
||||
|
||||
} else {
|
||||
card = randomCard();
|
||||
dealerCards.push(card);
|
||||
|
||||
const cardEl = createCardEl(card);
|
||||
wrapper = wrapCardInContainer(cardEl, true);
|
||||
dealerWrapper.appendChild(wrapper);
|
||||
dealerEls.push(wrapper);
|
||||
}
|
||||
|
||||
layoutOverlap(dealerEls, dealerWrapper);
|
||||
animateFromDeck(wrapper);
|
||||
|
||||
updateTotals();
|
||||
}
|
||||
|
||||
/* open all hidden dealer cards (flip) */
|
||||
function flipAllDealerHidden(){
|
||||
const hiddenWrappers = Array.from(dealerHiddenEls);
|
||||
|
||||
hiddenWrappers.forEach((wrapper, i) => {
|
||||
const backEl = wrapper.querySelector('.back-card');
|
||||
const cardObj = dealerHiddenCards[i];
|
||||
const realEl = createCardEl(cardObj);
|
||||
|
||||
setTimeout(()=>{
|
||||
// Flip: Mengubah isi wrapper (punggung -> depan)
|
||||
backEl.style.transform = 'rotateY(90deg)';
|
||||
backEl.style.opacity = '0';
|
||||
|
||||
realEl.style.transform = 'rotateY(-90deg)';
|
||||
realEl.style.opacity = '0';
|
||||
wrapper.appendChild(realEl);
|
||||
|
||||
setTimeout(() => {
|
||||
backEl.remove();
|
||||
realEl.style.transform = 'rotateY(0deg)';
|
||||
realEl.style.opacity = '1';
|
||||
|
||||
updateTotals();
|
||||
}, 200);
|
||||
|
||||
}, 300 + i*300);
|
||||
|
||||
});
|
||||
|
||||
setTimeout(()=>{
|
||||
dealerHiddenEls = [];
|
||||
dealerHiddenCards = [];
|
||||
}, 300 + hiddenWrappers.length*300);
|
||||
}
|
||||
|
||||
|
||||
/* ---------- dealer play & game end ---------- */
|
||||
function dealerPlay(){
|
||||
gamePhase = 'DEALER_TURN';
|
||||
const cycle = setInterval(()=>{
|
||||
if(calc(dealerCards) < 17){
|
||||
dealDealer(false);
|
||||
} else {
|
||||
clearInterval(cycle);
|
||||
finishResult();
|
||||
}
|
||||
}, 900);
|
||||
}
|
||||
|
||||
function finishResult(){
|
||||
gamePhase = 'END';
|
||||
const p = calc(playerCards);
|
||||
const d = calc(dealerCards);
|
||||
let msg = '';
|
||||
let payout = 0;
|
||||
|
||||
// Logic Payout
|
||||
if(p > 21) {
|
||||
msg = 'PLAYER BUST — YOU LOSE';
|
||||
} else if(d > 21) {
|
||||
msg = 'DEALER BUST — YOU WIN!';
|
||||
payout = currentBet * 2;
|
||||
} else if(p === 21 && playerCards.length === 2 && d !== 21) {
|
||||
msg = 'BLACKJACK! — YOU WIN! (3:2)';
|
||||
payout = currentBet + (currentBet * 1.5);
|
||||
} else if(p > d) {
|
||||
msg = 'YOU WIN!';
|
||||
payout = currentBet * 2;
|
||||
} else if(p < d) {
|
||||
msg = 'YOU LOSE!';
|
||||
} else {
|
||||
msg = 'PUSH (DRAW) — TARUHAN KEMBALI';
|
||||
payout = currentBet;
|
||||
}
|
||||
|
||||
// Update saldo dan UI
|
||||
balance += payout;
|
||||
balanceUI.innerText = balance;
|
||||
modalBalanceUI.innerText = balance;
|
||||
currentBet = 0;
|
||||
currentBetUI.innerText = currentBet;
|
||||
|
||||
showEnd(msg);
|
||||
}
|
||||
|
||||
/* ---------- end-screen handling ---------- */
|
||||
function showEnd(msg){
|
||||
document.getElementById('status').innerText = msg;
|
||||
hitBtn.disabled = true;
|
||||
standBtn.disabled = true;
|
||||
|
||||
endMessage.innerText = msg;
|
||||
endScreen.style.display = 'flex';
|
||||
playAgainBtn.focus();
|
||||
}
|
||||
|
||||
/* ---------- controls ---------- */
|
||||
function hit(){
|
||||
if(gamePhase !== 'PLAYING' || hitBtn.disabled) return;
|
||||
dealPlayer();
|
||||
if(calc(playerCards) > 21){
|
||||
setTimeout(() => finishResult(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
function stand(){
|
||||
if(gamePhase !== 'PLAYING' || standBtn.disabled) return;
|
||||
gamePhase = 'DEALER_TURN';
|
||||
hitBtn.disabled = true;
|
||||
standBtn.disabled = true;
|
||||
document.getElementById('status').innerText = 'DEALER TURN';
|
||||
|
||||
flipAllDealerHidden();
|
||||
setTimeout(()=> dealerPlay(), 300 + dealerHiddenEls.length*300);
|
||||
}
|
||||
|
||||
/* Fungsi untuk menangani deal dari modal betting */
|
||||
function handleDeal(){
|
||||
if(gamePhase !== 'BETTING') return;
|
||||
|
||||
const bet = parseInt(modalBetInput.value, 10);
|
||||
const minBet = 10;
|
||||
|
||||
if(isNaN(bet) || bet < minBet){
|
||||
modalBetError.innerText = `Taruhan minimum adalah $${minBet}.`;
|
||||
return;
|
||||
}
|
||||
if(bet > balance){
|
||||
modalBetError.innerText = 'Saldo tidak cukup.';
|
||||
return;
|
||||
}
|
||||
|
||||
// Set taruhan dan kurangi saldo
|
||||
currentBet = bet;
|
||||
balance -= currentBet;
|
||||
|
||||
// Update UI di stage utama
|
||||
balanceUI.innerText = balance;
|
||||
currentBetUI.innerText = currentBet;
|
||||
|
||||
// Sembunyikan Modal dan mulai permainan
|
||||
bettingScreen.style.display = 'none';
|
||||
modalBetError.innerText = '';
|
||||
|
||||
// Masuk ke fase bermain
|
||||
gamePhase = 'PLAYING';
|
||||
document.getElementById('status').innerText = 'YOUR TURN';
|
||||
|
||||
// Aktifkan HIT/STAND
|
||||
hitBtn.disabled = false;
|
||||
standBtn.disabled = false;
|
||||
|
||||
// Mulai permainan
|
||||
startGame();
|
||||
}
|
||||
|
||||
|
||||
/* ---------- restart / reset ---------- */
|
||||
function restart(){
|
||||
// clear state
|
||||
playerCards = [];
|
||||
dealerCards = [];
|
||||
playerEls.forEach(e=> e.remove());
|
||||
dealerEls.forEach(e=> e.remove());
|
||||
playerEls = [];
|
||||
dealerEls = [];
|
||||
dealerHiddenCards = [];
|
||||
dealerHiddenEls = [];
|
||||
|
||||
// hide end screen & UI reset
|
||||
endScreen.style.display = 'none';
|
||||
document.getElementById('status').innerText = 'PLACE YOUR BET';
|
||||
|
||||
// Reset UI kontrol
|
||||
hitBtn.disabled = true;
|
||||
standBtn.disabled = true;
|
||||
|
||||
gamePhase = 'BETTING';
|
||||
updateTotals();
|
||||
|
||||
// Tampilkan Modal Betting
|
||||
modalBalanceUI.innerText = balance;
|
||||
modalBetInput.value = Math.min(100, balance);
|
||||
bettingScreen.style.display = 'flex';
|
||||
modalBetInput.focus();
|
||||
}
|
||||
|
||||
/* ---------- initial deal ---------- */
|
||||
function startGame(){
|
||||
// Urutan dealing dengan jeda 200ms
|
||||
setTimeout(()=> dealPlayer(), 80);
|
||||
setTimeout(()=> dealDealer(true), 280);
|
||||
setTimeout(()=> dealPlayer(), 480);
|
||||
setTimeout(()=> dealDealer(true), 680);
|
||||
|
||||
setTimeout(() => {
|
||||
if(calc(playerCards) === 21){
|
||||
stand();
|
||||
}
|
||||
}, 800);
|
||||
|
||||
updateTotals();
|
||||
}
|
||||
|
||||
/* ---------- events ---------- */
|
||||
modalDealBtn.addEventListener('click', handleDeal);
|
||||
hitBtn.addEventListener('click', hit);
|
||||
standBtn.addEventListener('click', stand);
|
||||
playAgainBtn.addEventListener('click', restart);
|
||||
window.addEventListener('resize', ()=>{ layoutOverlap(playerEls, cardsWrapper); layoutOverlap(dealerEls, dealerWrapper); });
|
||||
|
||||
/* start - Panggil restart untuk memulai dengan modal betting */
|
||||
restart();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -134,3 +134,118 @@ footer{
|
||||
color:rgba(255,255,255,0.45);
|
||||
text-align:center
|
||||
}
|
||||
|
||||
.userbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 20px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
padding: 14px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
box-shadow: 0 8px 24px rgba(2, 6, 23, 0.45);
|
||||
}
|
||||
|
||||
.userbox .avatar {
|
||||
width: 58px;
|
||||
height: 58px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(180deg, #0e3b33, #0b2a2f);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
color: var(--accent);
|
||||
border: 2px solid rgba(246,198,79,0.4);
|
||||
box-shadow: 0 6px 14px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.userbox .info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.userbox .name {
|
||||
font-weight: 800;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.userbox .saldo {
|
||||
margin-top: 4px;
|
||||
font-size: 18px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.userbox .saldo span {
|
||||
color: var(--accent);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.userbox .status {
|
||||
margin-top: 2px;
|
||||
font-size: 16px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.gamename {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.num-box {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border: 1px solid #444;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
background: #1e1e1e;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.num-box input {
|
||||
height: 50px;
|
||||
width: 100px;
|
||||
font-size: 18px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: white;
|
||||
text-align: center;
|
||||
outline: none;
|
||||
line-height: 50px; /* base centering */
|
||||
display: flex; /* optical fix */
|
||||
align-items: center; /* optical fix */
|
||||
justify-content: center; /* ensures centered horizontally */
|
||||
}
|
||||
|
||||
.num-box input::-webkit-inner-spin-button,
|
||||
.num-box input::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.num-box .btn {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: none;
|
||||
background: #2b2b2b;
|
||||
color: white;
|
||||
font-size: 22px;
|
||||
cursor: pointer;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.num-box .btn:hover {
|
||||
background: #3a3a3a;
|
||||
}
|
||||
|
||||
.num-box .btn:active {
|
||||
background: #555;
|
||||
}
|
||||
|
||||
.plus, .minus {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
11
public/assets/js/menu.js
Normal file
11
public/assets/js/menu.js
Normal file
@ -0,0 +1,11 @@
|
||||
document.querySelector(".plus").addEventListener("click", () => {
|
||||
const input = document.querySelector(".num-box input");
|
||||
const step = Number(input.step) || 1;
|
||||
input.value = Number(input.value) + step;
|
||||
});
|
||||
|
||||
document.querySelector(".minus").addEventListener("click", () => {
|
||||
const input = document.querySelector(".num-box input");
|
||||
const step = Number(input.step) || 1;
|
||||
input.value = Math.max(1000, Number(input.value) - step);
|
||||
});
|
||||
57
public/index.php
Normal file
57
public/index.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
require "../includes/config.php";
|
||||
|
||||
if (!isset($_SESSION["uid"])) {
|
||||
header("Location: login.php");
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<a href="logout.php">Logout</a>
|
||||
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Hit & Run</title>
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div style="padding-right: 32px;">
|
||||
<div class="gamename card">
|
||||
Hit & Run <br>
|
||||
Hit or you Lose.
|
||||
</div>
|
||||
<div style="padding-top: 32px; display:flex; flex-direction:column; align-items:center;">
|
||||
<div class="num-box">
|
||||
<button class="btn minus">−</button>
|
||||
<input type="number" value="1000" style="margin-bottom: -1px;">
|
||||
<button class="btn plus">+</button>
|
||||
</div>
|
||||
<button class="btn btn-primary" id="playBtn">▶️ MAINKAN</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="userbox">
|
||||
<div class="avatar">P</div>
|
||||
|
||||
<div class="info">
|
||||
<div class="name"><?php echo $_SESSION["username"]; ?></div>
|
||||
<div class="saldo">Saldo: <span><?php echo $_SESSION["money"]; ?></span></div>
|
||||
<div class="status">Status: Masih Pemula Banghh....</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const playBtn = document.getElementById('playBtn');
|
||||
console.log("Startgame");
|
||||
</script>
|
||||
</body>
|
||||
<script src="assets/js/menu.js"></script>
|
||||
</html>
|
||||
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
<?php
|
||||
require_once "../includes/config.php";
|
||||
|
||||
@ -17,7 +15,7 @@
|
||||
$user = $result->fetch_assoc();
|
||||
|
||||
if (password_verify($password, $user["password"])) {
|
||||
$_SESSION["username"] = $user["username"];
|
||||
$_SESSION["uid"] = $user["uid"];
|
||||
header("Location: home.php");
|
||||
exit;
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user