Compare commits

..

91 Commits
main ... dev

Author SHA1 Message Date
Carolus Bramnatyo Seno Mahesworo
69e8769472 test lagi 2025-12-06 17:45:17 +07:00
faa6ace081 test WSL bram 2025-12-06 17:42:15 +07:00
62b04760f0 fix game bug notif 2025-12-06 17:21:39 +07:00
d60a408b08 test lagi 2025-12-05 15:19:01 +07:00
Carolus Bramnatyo Seno Mahesworo
e4e63dee36 Merge branch 'dev' of https://git-eng.ukwms.ac.id/2526-web/kelompok12-codebeater into dev 2025-12-05 15:09:31 +07:00
Carolus Bramnatyo Seno Mahesworo
6e8f86661d test 2025-12-05 15:09:08 +07:00
chocomett
edcafd3f15 fix: credit bug 2025-12-05 14:33:47 +07:00
Carolus Bramnatyo Seno Mahesworo
52b377c472 fix duration question 2025-12-05 13:10:15 +07:00
Carolus Bramnatyo Seno Mahesworo
6209797896 fix: music fixing 2025-12-05 12:37:08 +07:00
Carolus Bramnatyo Seno Mahesworo
de6b199a2c fix: fixing firstperson page 2025-12-03 17:01:12 +07:00
Matthew Florentino
15218074e9 fix: heart posisition 2025-12-03 16:44:34 +07:00
Matthew Florentino
616f0b14f8 fix: resize input at login register 2025-12-03 16:40:27 +07:00
MRMARCABLE
dc6af38dc1 feat:newslash 2025-12-03 16:34:31 +07:00
Carolus Bramnatyo Seno Mahesworo
76699f6be3 add sfx lagi 2025-12-03 16:22:33 +07:00
Carolus Bramnatyo Seno Mahesworo
97f09feccc add sfx 2025-12-03 16:13:11 +07:00
Carolus Bramnatyo Seno Mahesworo
cca4a7ebbc add: add music at leaderboard and game 2025-12-03 14:53:38 +07:00
Matthew Florentino
5699b5994f feat: add loading bar and remake thirdperson 2025-12-03 14:09:43 +07:00
Matthew Florentino
76bf80f502 feat: Finished feature heart, randomize questions, blood effect, shake effect 2025-12-03 10:47:02 +07:00
Matthew Florentino
dddb927c24 feat: change credit code but not clear enough 2025-12-03 09:12:20 +07:00
Carolus Bramnatyo Seno Mahesworo
4dca350c97 fix: perbaiki bug di leaderboard 2025-12-02 15:40:34 +07:00
Carolus Bramnatyo Seno Mahesworo
43a6539c68 hehe 2025-12-02 15:28:03 +07:00
MRMARCABLE
b2d3720f76 feat:cavelandingpage-creditbg 2025-12-02 14:57:12 +07:00
Carolus Bramnatyo Seno Mahesworo
3b6db2a425 add: add question for game 2025-12-02 14:54:40 +07:00
MRMARCABLE
8f2081e3b5 feat:damageeffect-hearteffect(2) 2025-12-02 12:37:03 +07:00
MRMARCABLE
36c6d3b98b feat:newSCENEdamaged 2025-12-02 12:33:40 +07:00
Matthew Florentino
25874a4643 feat: solve real rank 2025-12-02 12:09:16 +07:00
Matthew Florentino
b5672b2326 feat: fix ui leaderboard 2025-12-02 10:49:18 +07:00
Matthew Florentino
4e50ae9f5a feat: make credit and ongoing nav 2025-12-02 10:18:59 +07:00
Carolus Bramnatyo Seno Mahesworo
e1478cb88d feat: make a feature for leaderboard 2025-12-01 15:47:09 +07:00
Matthew Florentino
67cab5d06e fix: leaderboard as player 2025-12-01 15:09:25 +07:00
Carolus Bramnatyo Seno Mahesworo
87dff5cb9e Merge branch 'dev' of https://git-eng.ukwms.ac.id/2526-web/kelompok12-codebeater into dev 2025-12-01 15:04:37 +07:00
Carolus Bramnatyo Seno Mahesworo
f691c8e0d1 leaderboard fix 2025-12-01 15:03:56 +07:00
Matthew Florentino
3e2e1641fd feat:
fix: add score and design background
2025-12-01 12:23:56 +07:00
Carolus Bramnatyo Seno Mahesworo
4ee2118096 fix: fixing score bug 2025-12-01 12:13:20 +07:00
MRMARCABLE
dfd725d1b1 feast:campbgnewadjust6 2025-12-01 11:54:26 +07:00
MRMARCABLE
67293c34dc feast:campbgnewadjust5 2025-12-01 11:45:56 +07:00
MRMARCABLE
de7317f1aa feast:campbgnewadjust4 2025-12-01 11:40:06 +07:00
MRMARCABLE
36854f54ad feast:campbgnewadjust3 2025-12-01 11:36:58 +07:00
MRMARCABLE
a0d5f56ef3 feast:campbgnewadjust2 2025-12-01 11:26:25 +07:00
MRMARCABLE
a91d5d7078 feast:campbgnewadjust 2025-12-01 11:22:51 +07:00
MRMARCABLE
e080fb617e feast:loadscreen 2025-12-01 11:12:18 +07:00
MRMARCABLE
033c07490d feast:newBGforBOSSFIGHTandSCOREBOARD 2025-12-01 10:29:56 +07:00
MRMARCABLE
6c4d017480 feast:testBGBOSSFIGHT 2025-12-01 09:59:37 +07:00
Matthew Florentino
e1af8fc497 test: otw diambil bram 2025-12-01 09:34:11 +07:00
Matthew Florentino
409d7dfe9f feat: fitur utama game and have err at adding score 2025-12-01 09:04:14 +07:00
Matthew Florentino
280f6d0639 fix: fitur register 2025-11-28 11:45:35 +07:00
Matthew Florentino
267e5d1c38 design: changes image and animate 2025-11-27 17:09:15 +07:00
Matthew Florentino
e236a906f3 fix: fixing redirect page 2025-11-27 16:42:20 +07:00
Matthew Florentino
24ae6475eb fix: fix logic login register 2025-11-27 15:38:30 +07:00
Matthew Florentino
bfe36fbd4f fix: index.php and user.sql 2025-11-27 10:22:10 +07:00
Matthew Florentino
b06b6a4160 fix: add style onboard 2025-11-27 10:01:41 +07:00
Matthew Florentino
67956d1538 fix: done rebase 2025-11-27 09:42:01 +07:00
Matthew Florentino
dda9cf29f6 fix: index.php 2025-11-27 09:21:19 +07:00
6c503fe010 Merge pull request (#7) from href into dev 2025-11-26 21:09:16 -05:00
Matthew Florentino
61a5fedd6e design: ambil gambar 2025-11-27 09:04:35 +07:00
Matthew Florentino
1b1d74aefc design: Ambil folder Design dari branch dev 2025-11-26 17:22:24 +07:00
Matthew Florentino
b8be39b1e4 bug: mau solve bug 2025-11-26 17:21:05 +07:00
MRMARCABLE
d0e7c9e867 feast:cavebossfight 2025-11-26 17:14:25 +07:00
Matthew Florentino
ca72628776 feat: add logout.php and onboard.php 2025-11-26 16:46:34 +07:00
ea5b6d74c4 merge from notif to dev (#6) 2025-11-26 04:41:57 -05:00
Matthew Florentino
e848cb31fc style: final style notif 2025-11-26 11:01:10 +07:00
Matthew Florentino
2dd889153b feat: wait beacuse have bug at index.php 2025-11-26 10:48:57 +07:00
Carolus Bramnatyo Seno Mahesworo
2282f02005 add: dumpsql file 2025-11-25 16:58:23 +07:00
Carolus Bramnatyo Seno Mahesworo
579ff78460 Merge branch 'dev' of https://git-eng.ukwms.ac.id/2526-web/kelompok12-codebeater into dev 2025-11-25 16:51:24 +07:00
71e7f7a48e feat: Styling game first and third person merge from game 2025-11-25 04:27:27 -05:00
Matthew Florentino
c3e0498160 feat: add border 2025-11-25 16:23:36 +07:00
Matthew Florentino
4749fb123e feat: Ambil folder Design dari branch dev #2 2025-11-25 16:07:14 +07:00
Matthew Florentino
b69f72101a feat: Ambil folder Design dari branch dev 2025-11-25 16:04:25 +07:00
Matthew Florentino
5e713e2c4d style: styling game.css 2025-11-25 15:57:43 +07:00
Matthew Florentino
0ec677058e feat: thirdperson animation 2025-11-25 10:51:33 +07:00
MRMARCABLE
9aec565e0a feast:PYTHONBOSS 2025-11-24 16:36:40 +07:00
MRMARCABLE
55a4ee8e2e design: add file 2025-11-24 15:47:41 +07:00
Carolus Bramnatyo Seno Mahesworo
6311cab5a2 feat: make a leaderboard feature 2025-11-24 14:41:42 +07:00
Carolus Bramnatyo Seno Mahesworo
f9fc7ba011 feat: fixing bug at login page 2025-11-24 13:00:13 +07:00
Carolus Bramnatyo Seno Mahesworo
157cf7ed5c feat: fixed register page bug 2025-11-24 12:42:56 +07:00
Matthew Florentino
fb1ebd6fee style: styling leaderboard 2025-11-24 11:16:48 +07:00
Matthew Florentino
7e6d71d67a add folder assets form branch design to backup 2025-11-24 10:53:10 +07:00
Matthew Florentino
9bf0395d24 style: styling index register and leaderboard ongoing 2025-11-24 10:43:05 +07:00
Matthew Florentino
6b62df95f0 fix: fixed bug css cache at browser and fixing named container docker 2025-11-24 10:15:04 +07:00
Matthew Florentino
2e1bb8c477 feat: add all file 2025-11-18 10:01:00 +07:00
c66ef70605 fix : merge conflict 2025-11-17 21:18:17 -05:00
Carolus Bramnatyo Seno Mahesworo
cd93129ba3 fix: merge conflict 2025-11-18 09:15:49 +07:00
Carolus Bramnatyo Seno Mahesworo
e3dc5c9516 Merge branch 'dev' of https://git-eng.ukwms.ac.id/2526-web/kelompok12-codebeater into feat/login 2025-11-18 08:57:22 +07:00
4784b81db1 style/login: merge commit 2025-11-17 20:55:08 -05:00
Matthew Florentino
de8e602fe1 style: fix bug 2025-11-14 14:45:29 +07:00
Carolus Bramnatyo Seno Mahesworo
63b488fcec feat: login feature 2025-11-14 14:27:30 +07:00
Matthew Florentino
379c264987 style: add basic structure index.php and global css 2025-11-13 20:35:57 +07:00
750816b555 Merge pull request 'feat: add structure file' (#2) from feat/file into dev 2025-11-13 08:08:46 -05:00
Matthew Florentino
137af42d12 feat: add structure file 2025-11-13 20:03:43 +07:00
57255b579a Merge pull request 'feat: add dockerfile' (#1) from feat/file into dev 2025-11-13 02:59:06 -05:00
Matthew Florentino
2d4666717e feat: add dockerfile 2025-11-13 14:48:42 +07:00
64 changed files with 1850 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.docs.txt

11
coba.html Normal file
View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>hai</h1>
</body>
</html>

50
docker-compose.yaml Normal file
View File

@ -0,0 +1,50 @@
version: "3.8"
services:
phpapache:
build:
context: .
dockerfile: Dockerfile
container_name: codebeater_phpapache
ports:
- "8080:80"
volumes:
- ./src:/var/www/html
depends_on:
- db
networks:
- codebeater_net
db:
image: mysql:8.0
container_name: codebeater_mysql
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: codebeater
MYSQL_USER: admin
MYSQL_PASSWORD: admin
volumes:
- db_codebeater:/var/lib/mysql
networks:
- codebeater_net
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
container_name: codebeater_phpmyadmin
ports:
- "8081:80"
environment:
PMA_HOST: db
PMA_PORT: 3306
depends_on:
- db
networks:
- codebeater_net
volumes:
db_codebeater:
networks:
codebeater_net:
driver: bridge

7
dockerfile Normal file
View File

@ -0,0 +1,7 @@
FROM php:8.2-apache
RUN docker-php-ext-install mysqli
COPY ./src /var/www/html
EXPOSE 80

11
logout.php Normal file
View File

@ -0,0 +1,11 @@
<?php
session_start();
unset($_SESSION['loggedin']);
unset($_SESSION['username']);
unset($_SESSION['id']);
$_SESSION['flash'] = "Logout berhasil!";
header("Location: index.php");
exit();

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
src/assets/music/credit.mp3 Normal file

Binary file not shown.

BIN
src/assets/music/game.mp3 Normal file

Binary file not shown.

BIN
src/assets/music/heart.mp3 Normal file

Binary file not shown.

BIN
src/assets/music/hover.mp3 Normal file

Binary file not shown.

BIN
src/assets/music/hurt.mp3 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/assets/music/slash.mp3 Normal file

Binary file not shown.

13
src/config/db.php Normal file
View File

@ -0,0 +1,13 @@
<?php
$hostname = "db";
$username = "admin";
$password = "admin";
$database = "codebeater";
$db = mysqli_connect($hostname, $username, $password, $database);
if(!$db){
die("Koneksi database gagal. Error: " . mysqli_connect_error());
}

196
src/credit.html Normal file
View File

@ -0,0 +1,196 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<link rel="stylesheet" href="/css/global.css">
<link rel="stylesheet" href="/css/style.css">
<style>
:root {
--height: 500px;
}
</style>
</head>
<body>
<audio id="bgm-crdt" src="/assets/music/credit.mp3" autoplay></audio>
<div class="container-credits" id="credits">
<a class="back" href="onboard.php" data-aos="fade-in" data-aos-duration="3000"></a>
<div class="credits">
<div class="credits-inner" id="creditsInner">
<div class="block">
<h1>👾 codebeater 👾</h1>
<div class="role">lecturer Counselors</div>
<div class="name">Bu Devi</div>
<div class="name">Koh Andrew</div>
<div class="role">Development Team</div>
<div class="name">Owen</div>
<div class="name">Matthew Florentino</div>
<div class="name">Carolus Bramantyo</div>
<div class="name">Yohannes Marcel</div>
<div class="role">Frontend Developer</div>
<div class="name">Yohannes Marcel</div>
<div class="name">Matthew Florentino</div>
<div class="name">Owen</div>
<div class="role">backend Developer</div>
<div class="name">Carolus Bramantyo</div>
<div class="name">Matthew Florentino</div>
<div class="role">Game Designers</div>
<div class="name">Yohannes Marcel</div>
<div class="role">Assets Designers</div>
<div class="name">Yohannes Marcel</div>
<div class="role">Questions Designers</div>
<div class="name">Yohannes Marcel</div>
<div class="name">Owen</div>
<div class="role">CSS Specialist</div>
<div class="name">Matthew Florentino</div>
<div class="role">JS Specialist</div>
<div class="name">Matthew Florentino</div>
<div class="role">PHP Specialist</div>
<div class="name">Carolus Bramantyo</div>
<div class="role">SQL Specialist</div>
<div class="name">Carolus Bramantyo</div>
<div class="role">Advicer</div>
<div class="name">Rafael</div>
<div class="name">Erlang</div>
<div class="name">Bu Devi</div>
<div class="name">koh Andrew</div>
<div class="role">Libary</div>
<div class="name">Animate on Scroll</div>
<div class="role">Font</div>
<div class="name">Jetbrains Mono</div>
<div class="role">Reference Game</div>
<div class="name">Undertale</div>
<div class="name">Soul Knight</div>
<div class="name">Tomb of the Mask</div>
<div class="role">Reference Music</div>
<div style="height:40px;"></div>
<div style="height:40px"></div>
</div>
<div class="block">
<h1>👾 codebeater 👾</h1>
<div class="role">lecturer Counselors</div>
<div class="name">Bu Devi</div>
<div class="name">Koh Andrew</div>
<div class="role">Development Team</div>
<div class="name">Owen</div>
<div class="name">Matthew Florentino</div>
<div class="name">Carolus Bramantyo</div>
<div class="name">Yohannes Marcel</div>
<div class="role">Frontend Developer</div>
<div class="name">Yohannes Marcel</div>
<div class="name">Matthew Florentino</div>
<div class="name">Owen</div>
<div class="role">backend Developer</div>
<div class="name">Carolus Bramantyo</div>
<div class="name">Matthew Florentino</div>
<div class="role">Game Designers</div>
<div class="name">Yohannes Marcel</div>
<div class="role">Assets Designers</div>
<div class="name">Yohannes Marcel</div>
<div class="role">Questions Designers</div>
<div class="name">Yohannes Marcel</div>
<div class="name">Owen</div>
<div class="role">CSS Specialist</div>
<div class="name">Matthew Florentino</div>
<div class="role">JS Specialist</div>
<div class="name">Matthew Florentino</div>
<div class="role">PHP Specialist</div>
<div class="name">Carolus Bramantyo</div>
<div class="role">SQL Specialist</div>
<div class="name">Carolus Bramantyo</div>
<div class="role">Advicer</div>
<div class="name">Rafael</div>
<div class="name">Erlang</div>
<div class="name">Bu Devi</div>
<div class="name">koh Andrew</div>
<div class="role">Libary</div>
<div class="name">Animate on Scroll</div>
<div class="role">Font</div>
<div class="name">Jetbrains Mono</div>
<div class="role">Reference Game</div>
<div class="name">Undertale</div>
<div class="name">Soul Knight</div>
<div class="name">Tomb of the Mask</div>
<div class="role">Reference Music</div>
<div style="height:40px;"></div>
<div style="height:40px"></div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
const bgm = document.getElementById("bgm-crdt");
bgm.volume = 0.2;
bgm.play()
const inner = document.getElementById("creditsInner");
let y = 0;
let blockH = inner.scrollHeight / 2;
const speed = 40;
function loop() {
y -= speed / 60;
if (y <= -blockH) y = 0;
inner.style.transform = `translateY(${y}px)`;
requestAnimationFrame(loop);
}
window.addEventListener("resize", () => {
blockH = inner.scrollHeight / 2;
y = 0;
});
loop();
});
</script>
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<script>
AOS.init();
</script>
</body>
</html>

205
src/css/game.css Normal file
View File

@ -0,0 +1,205 @@
.container-third .bg {
width: 100%;
height: 100dvh;
}
.container-third .bg {
position: relative;
}
.container-third .bg img {
width: 100%;
position: absolute;
bottom: 0;
image-rendering: pixelated;
background-repeat: no-repeat;
background-size: cover;
}
.container-third .hero img {
width: 150px;
position: absolute;
bottom: 100px;
left: 50px;
image-rendering: pixelated;
background-repeat: no-repeat;
background-size: cover;
}
.container-third .boss img {
width: 300px;
position: absolute;
bottom: 100px;
right: 50px;
image-rendering: pixelated;
background-repeat: no-repeat;
background-size: cover;
}
.container-first {
background-image: url(/assets/Design/newBGBOSSFIGHT.gif);
background-repeat: no-repeat;
background-size: cover;
image-rendering: pixelated;
background-position: center;
}
.container-first .content .boss {
width: 100%;
height: 100dvh;
position: relative;
animation: beat 2s infinite;
transform-origin: center;
}
.container-first .content .boss img {
width: 600px;
position: absolute;
bottom: 100px;
left: 50%;
transform: translateX(-50%);
image-rendering: pixelated;
background-repeat: no-repeat;
background-size: cover;
}
.container-first .content .boss .dmg {
width: 600px;
position: absolute;
bottom: 100px;
left: 50%;
transform: translateX(-50%);
image-rendering: pixelated;
background-repeat: no-repeat;
background-size: cover;
display: none;
}
@keyframes shake {
0% {
transform: translateX(-50%);
}
25% {
transform: translateX(calc(-50% - 5px));
}
50% {
transform: translateX(calc(-50% + 5px));
}
75% {
transform: translateX(calc(-50% - 5px));
}
100% {
transform: translateX(-50%);
}
}
.animate-shake {
animation: shake 0.3s ease-in-out;
}
.container-first .hearts {
position: absolute;
top: 322px;
left: 50%;
transform: translateX(-50%);
image-rendering: pixelated;
z-index: 999;
}
.container-first .hearts img {
width: 50px;
}
.container-first .content .quiz {
width: 1000px;
height: 200px;
bottom: 40px;
left: 50%;
transform: translateX(-50%);
background-color: #101010f5;
position: absolute;
display: flex;
justify-content: start;
text-align: center;
align-content: center;
padding: 10px;
display: flex;
flex-direction: column;
border-radius: 10px;
border: 10px solid white;
z-index: 1;
}
.container-first .content .quiz h2 {
margin-bottom: 30px;
padding: 10px;
color: #ffdf12;
font-size: 40px;
}
.container-first .content .quiz #btn-answer {
color: #ffdf12;
display: flex;
justify-content: center;
}
.container-first .content .quiz #btn-answer button {
padding: 10px;
color: #ffdf12;
font-size: 30px;
background-color: #f7e62e34;
margin: 5px;
border-radius: 10px;
cursor: pointer;
}
@keyframes beat {
0% {
transform: scale(1);
}
50% {
transform: scale(0.95);
}
100% {
transform: scale(1);
}
}
.container-load {
position: relative;
min-height: 100dvh;
}
.container-load .bg {
background-size: cover;
width: 100%;
height: 100dvh;
position: absolute;
z-index: -999;
}
.container-load .anm {
font-size: 25px;
background-size: cover;
position: absolute;
bottom: 50%;
text-align: center;
width: 100%;
}
.container-load .hero {
width: 100px;
position: absolute;
image-rendering: pixelated;
bottom: -5%;
left: 5%;
transform: translate(-50%, -50%);
z-index: 999;
}

12
src/css/global.css Normal file
View File

@ -0,0 +1,12 @@
@import url('https://fonts.googleapis.com/css2?family=Jersey+15&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap');
*{
font-family: "Jersey 15", sans-serif;
margin: 0;
padding: 0;
}
body {
color: white;
background-color: black;
}

353
src/css/style.css Normal file
View File

@ -0,0 +1,353 @@
.container-login {
display: flex;
width: 100%;
height: 100dvh;
flex-direction: column;
justify-content: center;
align-items: center;
}
.container-login h1 {
font-size: 130px;
font-weight: 400;
}
.container-login form {
text-align: center;
padding: 30px;
}
.container-login form h2 {
margin-bottom: 20px;
font-size: 40px;
text-transform: capitalize;
}
.container-login form input {
margin-bottom: 10px;
width: 300px;
height: 40px;
border-radius: 6px;
font-size: 20px;
text-align: center;
background-color: black;
border: 1px solid white;
color: white;
}
.container-login form input::placeholder {
color: #919191;
}
.container-login form button {
border-radius: 6px;
width: 300px;
height: 40px;
margin-top: 40px;
font-size: 30px
}
.container-login form p {
margin-top: 10px;
}
.container-login form p a {
color: white;
text-decoration: none;
}
.container-login form p a span {
color: yellow;
}
.container-register {
display: flex;
width: 100%;
height: 100dvh;
flex-direction: column;
justify-content: center;
align-items: center;
}
.container-register h1 {
font-size: 120px;
font-weight: 400;
}
.container-register form {
text-align: center;
padding: 30px;
}
.container-register form h2 {
margin-bottom: 10px;
font-size: 30px;
text-transform: capitalize;
}
.container-register form input {
margin-bottom: 10px;
width: 300px;
height: 40px;
border-radius: 6px;
font-size: 20px;
text-align: center;
background-color: black;
border: 1px solid white;
color: white;
}
.container-register form input::placeholder {
color: #919191;
}
.container-register form button {
border-radius: 6px;
width: 300px;
height: 40px;
margin-top: 10px;
font-size: 30px
}
.container-register form p {
margin-top: 10px;
}
.container-register form p a {
color: white;
text-decoration: none;
}
.container-register form p a span {
color: yellow;
}
.container-board {
display: flex;
justify-content: space-around;
align-items: center;
height: 100dvh;
/* Hapus properti background dari sini dan pindahkan ke ::before */
/* Tambahkan posisi relatif agar pseudo-element bisa diposisikan absolut di dalamnya */
position: relative;
/* Pastikan konten di dalam container ada di atas latar */
z-index: 1;
}
/* Pseudo-element untuk menampung gambar latar transparan */
.container-board::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* Pindahkan properti background Anda ke sini */
background-image: url(/assets/Design/CampFire8WESFIX!-export.png);
background-repeat: no-repeat;
background-size: cover;
background-position: center;
image-rendering: pixelated;
/* >>> INI KUNCINYA: Atur opasitasnya di sini <<< */
opacity: 1;
/* Contoh nilai 40% transparan */
/* Pindahkan latar ini ke lapisan paling bawah */
z-index: -1;
}
.container-board .chara {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
.container-board .chara .character {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
flex-direction: column;
}
.container-board .chara .character img {
width: 300px;
image-rendering: pixelated;
margin: 20px;
}
.container-board .menu {
margin: 0 auto;
border-radius: 6px;
width: 400px;
height: 40px;
align-content: center;
}
.container-board .board table {
width: 600px;
margin: 40px auto;
border-collapse: collapse;
/*menghilangkan gap antar border*/
font-family: "Segoe UI", Tahoma, sans-serif;
color: white;
font-weight: 200;
font-size: 20px;
border-radius: 10px;
overflow: hidden;
}
.container-board .board table th,
td {
border: 5px solid #ffffff;
padding: 14px 18px;
white-space: nowrap;
text-align: center;
}
.container-board .board table thead th {
font-weight: 400;
font-size: 20px;
color: #bbd000;
letter-spacing: .4px;
}
.container-board .board table {
background: #0b0e00f3;
}
.container-board .board table tbody tr:hover {
background: #c1fc0032;
}
.container-board .back {
color: #ffff009a;
text-decoration: none;
font-size: 30px;
position: absolute;
z-index: 99999;
left: 2%;
top: 5%;
}
.container-board .back:hover {
color: yellow;
}
.container-onboard {
display: flex;
width: 100%;
height: 100dvh;
flex-direction: column;
justify-content: center;
align-items: center;
background-image: url(/assets/Design/landingPage.png);
background-position: center;
}
.container-onboard h1 {
font-size: 150px;
color: yellow;
font-weight: 400;
margin-bottom: 50px;
}
.container-onboard .menu {
display: flex;
flex-direction: column;
text-align: center;
}
.container-onboard .menu a {
padding: 10px 80px;
background-color: #87871b23;
margin: 8px;
border-radius: 5px;
font-size: 30px;
color: yellow;
border: 1px solid #8170029f;
text-decoration: none;
}
.container-onboard .menu a:hover {
transition: 0.4s ease-out;
color: #dd85fa;
border: 1px solid #dd85fa;
background-color: #871b8323;
}
.container-credits {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-image: url(/assets/Design/creditbg.png);
margin: 0;
background-position: center;
background-size:cover ;
}
.container-credits .credits {
width: 100%;
height: var(--height);
overflow: hidden;
border-radius: 8px;
padding: 24px 12px;
position: relative;
}
.container-credits .credits .credits-inner {
display: flex;
flex-direction: column;
transform: translateY(0);
will-change: transform;
}
.container-credits .credits .credits-inner h1 {
font-size: 150px;
color: yellow;
font-weight: 400;
margin-bottom: 50px;
text-align: center;
}
.container-credits .credits .credits-inner .role {
font-weight: 400;
color: yellow;
margin-top: 10px;
text-align: center;
padding: 6px 0;
font-size: 50px;
line-height: 1.25;
text-shadow: 0 1px 0 rgba(0, 0, 0, .6);
}
.container-credits .credits .credits-inner .name {
font-weight: 400;
color: #ffffff;
font-size: 14px;
text-align: center;
padding: 6px 0;
font-size: 30px;
line-height: 1.25;
text-shadow: 0 1px 0 rgba(0, 0, 0, .6);
}
.container-credits .back {
color: #ffff009a;
text-decoration: none;
font-size: 30px;
position: absolute;
z-index: 99999;
left: 2%;
top: 5%;
}
.container-credits .back:hover {
color: yellow;
}

52
src/game/firstperson.html Normal file
View File

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>firstperson</title>
<link rel="stylesheet" href="/css/global.css">
<link rel="stylesheet" href="/css/game.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
</head>
<body>
<audio id="bgm" src="/assets/music/game.mp3" loop autoplay></audio>
<audio id="sfx" src="/assets/music/slash.mp3"></audio>
<audio id="sfxhrt" src="/assets/music/hurt.mp3"></audio>
<div class="container-first">
<div class="content">
<div class="boss">
<img id="boss" src="/assets/Design/PYTHON-BOSSFIGHTMODEFINALt.gif" alt="">
<img id="dmg" class="dmg" src="/assets/Design/damageeffectNEWSLASH.gif"/>
</div>
<div class="hearts" id="hrt">
<img id="h1" src="/assets/Design/Heartfull.png">
<img id="h2" src="/assets/Design/Heartfull.png">
<img id="h3" src="/assets/Design/Heartfull.png">
</div>
<div class="quiz">
<h2 id="question"></h2>
<div id="btn-answer">
<button class="btn"></button>
<button class="btn"></button>
<button class="btn"></button>
<button class="btn"></button>
</div>
</div>
</div>
</div>
<script type="module" src="/js/firstperson.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
const bgm = document.getElementById("bgm");
bgm.volume = 0.1;
bgm.loop(true)
bgm.play()
});
</script>
</body>
</html>

18
src/game/loading.html Normal file
View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Loading ...</title>
<link rel="stylesheet" href="/css/global.css">
<link rel="stylesheet" href="/css/game.css">
</head>
<body>
<div class="container-load">
<p id="wellcome-message" class="anm" ><span style="color: yellow; font-size: 40px;">Welcome to the Python Quiz!</span><br>Youll face multiple-choice questions designed to test your logic and Python skills. <br>Lets see how well you can outsmart the code!</p>
<img id="hero" class="hero" src="/assets/Design/KNIGHTPIXLETPP.gif" alt="">
<img class="bg" src="/assets/Design/LOADSCREEN.gif" alt="">
</div>
<script src="/js/load.js"></script>
</body>
</html>

27
src/game/thirdperson.html Normal file
View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>thirdperson</title>
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<link rel="stylesheet" href="/css/global.css">
<link rel="stylesheet" href="/css/game.css">
</head>
<body>
<div class="container-third">
<div class="bg">
<img src="/assets/Design/wayland.png" alt="bg">
</div>
<div class="hero">
<img id="hero" src="/assets/Design/KNIGHTPIXLETPP.gif" alt="">
</div>
<div class="boss">
<img id="boss" src="/assets/Design/for-NewPythonGift.gif" alt="">
</div>
</div>
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<script>AOS.init();</script>
<script src="/js/thirdperson.js"></script>
</body>
</html>

80
src/index.php Normal file
View File

@ -0,0 +1,80 @@
<?php
session_start();
include "config/db.php";
if (isset($_POST['login'])) {
$username = trim($_POST['username']);
$password = trim($_POST['password']);
if ($username === "" || $password === "") {
$_SESSION['flash'] = "Data harus lengkap!";
} else {
$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $db->prepare($sql); // agar aman dari sql injection
$stmt->bind_param("s", $username); // agar rapi tidak muncul di bagian atas query
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 1) {
$user = $result->fetch_assoc();
if (password_verify($password, $user['password'])) {
$_SESSION['loggedin'] = true;
$_SESSION['username'] = $user['username'];
$_SESSION['id'] = $user['id'];
$_SESSION['flash'] = "Wellcome to Dungeon, player $username";
header("Location: onboard.php");
exit();
} else {
$_SESSION['flash'] = "Password salah!";
}
} else {
$_SESSION['flash'] = "Username tidak ditemukan!";
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>login</title>
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<link rel="stylesheet" href="/css/global.css">
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div class="container-login">
<?php
include "notif.php";
if (isset($_SESSION['flash'])) {
echo "<script>showNotif(" . json_encode($_SESSION['flash']) . ");</script>";
unset($_SESSION['flash']);
}
?>
<h1 data-aos="zoom-out" data-aos-duration="1000">codebeater</h1>
<form class="login-form" action ="index.php" method="POST">
<h2 data-aos="fade-up" data-aos-duration="1000">Login to your account</h2>
<input type="text" name="username" id="username" placeholder="input your username" data-aos="fade-up" data-aos-duration="2000"><br>
<input type="password" name="password" id="password" placeholder="input your password" data-aos="fade-up" data-aos-duration="2000"><br>
<button type="submit" name="login" data-aos="fade-up" data-aos-duration="3000">LOGIN</button>
<p data-aos="fade-up" data-aos-duration="3000"><a href="register.php">don't have account yet?<span> register now!</span></a></p>
</form>
<div id="notif" class="notif"></div>
</div>
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<script>
AOS.init();
</script>
</body>
</html>

168
src/js/firstperson.js Normal file
View File

@ -0,0 +1,168 @@
import { questions } from "./soal.js";
const questionElement = document.getElementById("question")
const answerBtn = document.getElementById("btn-answer")
let currentQuestionIndex = 0;
let score = 0;
let wrongCount = 0;
let maxWrong = 3;
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
function startQuiz(){
currentQuestionIndex = 0;
score = 0;
shuffle(questions);
showQuestion();
}
function showQuestion(){
resetState();
let currentQuestion = questions[currentQuestionIndex]
let questionNumber = currentQuestionIndex + 1
questionElement.innerHTML = questionNumber + ". " + currentQuestion.question;
currentQuestion.answers.forEach(answer => {
const button = document.createElement("button");
button.innerHTML = answer.text;
button.classList.add("btn");
answerBtn.appendChild(button);
button.dataset.correct = answer.correct;
button.addEventListener("click", selectAnswer)
});
}
function resetState(){
while(answerBtn.firstChild){
answerBtn.removeChild(answerBtn.firstChild)
}
}
function updateHearts(){
const hearts = [
document.getElementById("h1"),
document.getElementById("h2"),
document.getElementById("h3")
];
hearts.forEach((h, i) => {
if(i < wrongCount){
h.src = "/assets/Design/HeartEmpty.png";
} else {
h.src = "/assets/Design/Heartfull.png";
}
});
}
function dmg(){
const dmg = document.getElementById("dmg");
dmg.style.display = "block";
setTimeout(() => {
dmg.style.display = "none";
}, 450);
}
function shake(el){
el.classList.remove("animate-shake");
void el.offsetWidth;
el.classList.add("animate-shake");
el.addEventListener("animationend", () => {
el.classList.remove("animate-shake");
}, { once: true });
}
function selectAnswer(e){
const selectedBtn = e.target;
const isCorrect = selectedBtn.dataset.correct === "true";
if(isCorrect){
selectedBtn.classList.add("correct");
score += 10;
shake(document.getElementById("boss"))
dmg();
const bgm = document.getElementById("sfx");
bgm.play()
} else {
selectedBtn.classList.add("Incorrect");
wrongCount ++;
shake(document.getElementById("hrt"))
updateHearts();
const bgm = document.getElementById("sfxhrt");
bgm.play()
if(wrongCount >= maxWrong){
setTimeout(()=>{
showScore();
}, 500);
return;
}
}
Array.from(answerBtn.children).forEach(button => {
if(button.dataset.correct === "true") button.classList.add("correct");
button.disabled = true;
});
setTimeout(nextQuestion, 500)
}
function showScore(){
resetState();
const show = questionElement.innerHTML = `you scored ${score} out of 200 !`;
postScore(score);
}
function handleNextBtn(){
currentQuestionIndex++;
if(currentQuestionIndex < questions.length){
showQuestion();
} else {
showScore();
}
}
function nextQuestion(){
if(currentQuestionIndex < questions.length){
handleNextBtn()
} else {
showScore()
}
}
function postScore(score){
fetch('/score.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ score: score })
})
.then(r => r.json())
.then(data => {
console.log("Server response:", data);
if(data.success || data.message === "Score accumulated") {
setTimeout(() => {
window.location.href = "../leaderboard.php";
}, 3000);
} else {
setTimeout(() => {
window.location.href = "../leaderboard.php";
}, 3000);
}
})
.catch(err => {
console.error("Fetch error:", err);
alert("Terjadi kesalahan koneksi.");
});
}
startQuiz()

3
src/js/load.js Normal file
View File

@ -0,0 +1,3 @@
setTimeout(()=> {
window.location.href = "/game/firstperson.html"
}, 5000)

0
src/js/main.js Normal file
View File

182
src/js/soal.js Normal file
View File

@ -0,0 +1,182 @@
export const questions = [
{
question: "what is Python ?",
answers: [
{text: "Programming Lang", correct: true},
{text: "Animal", correct: false},
{text: "Danger", correct: false},
{text: "All Answer Correct", correct: false},
]
},
{
question: "Data type at python ?",
answers: [
{text: "Docx", correct: false},
{text: "CSV", correct: false},
{text: "String", correct: true},
{text: "SQL", correct: false},
]
},
{
question: "Index at python start from ?",
answers: [
{text: "1", correct: false},
{text: "-1", correct: false},
{text: "10", correct: false},
{text: "0", correct: true},
]
},
{
question: "How do you start a comment in Python code ?",
answers: [
{text: "// This is a comment", correct: true},
{text: "/* This is a comment */", correct: false},
{text: "`this is comment`", correct: false},
{text: "# This is a comment", correct: false},
]
},
{
question: "What is the result of the following operation ? (print('5'+'5'))",
answers: [
{text: "10", correct: false},
{text: "55", correct: true},
{text: "error", correct: false},
{text: "NaN", correct: false},
]
},
{
question: "Correct string format ?",
answers: [
{text: "'bahlil'", correct: true},
{text: "(bahlil)", correct: false},
{text: "[bahlil]", correct: false},
{text: "{bahlil}", correct: false},
]
},
{
question: "Correct loop syntax ?",
answers: [
{text: "for i in range(5):", correct: true},
{text: "loop 5 time", correct: false},
{text: "foreach i in 5", correct: false},
{text: "repeat", correct: false},
]
},
{
question: "Function to get user input ?",
answers: [
{text: "scan()", correct: false},
{text: "input()", correct: true},
{text: "error", correct: false},
{text: "get()", correct: false},
]
},
{
question: "Convert integer to string ?",
answers: [
{text: "text(5)", correct: false},
{text: "toStr(5)", correct: false},
{text: "str(5)", correct: true},
{text: "char(5)", correct: false},
]
},
{
question: "Stop a loop ?",
answers: [
{text: "break", correct: true},
{text: "stop", correct: false},
{text: "exit", correct: false},
{text: "kill", correct: false},
]
},
{
question: "Symbol for tuples?",
answers: [
{text: "[ ]", correct: false},
{text: "{ }", correct: false},
{text: "( )", correct: true},
{text: "< >", correct: false},
]
},
{
question: "Output of int(3.9) ?",
answers: [
{text: "4", correct: false},
{text: "3,9", correct: false},
{text: "3", correct: true},
{text: "tiga koma sembilan", correct: false},
]
},
{
question: "Find max number ?",
answers: [
{text: "top()", correct: false},
{text: "max()", correct: true},
{text: "high()", correct: false},
{text: "largest()", correct: false},
]
},
{
question: '(3 * "A") output ?',
answers: [
{text: "error", correct: false},
{text: "none", correct: false},
{text: "AAA", correct: true},
{text: "A3A", correct: false},
]
},
{
question: "Logical OR operator ?",
answers: [
{text: "||", correct: false},
{text: "%%", correct: false},
{text: "or", correct: true},
{text: "&&", correct: false},
]
},
{
question: "result of not True ?",
answers: [
{text: "true", correct: false},
{text: "false", correct: true},
{text: "null", correct: false},
{text: "0", correct: false},
]
},
{
question: "Check if item exists ?",
answers: [
{text: "exists", correct: false},
{text: "inside", correct: false},
{text: "in", correct: true},
{text: "has", correct: false},
]
},
{
question: "x += 1 means?",
answers: [
{text: "x = 1", correct: false},
{text: "x = x + 1", correct: true},
{text: "x = x - 1", correct: false},
{text: "idk", correct: false},
]
},
{
question: "Define a class ?",
answers: [
{text: "struct", correct: false},
{text: "object", correct: false},
{text: "type", correct: false},
{text: "class", correct: true},
]
},
{
question: "how much data type in python ?",
answers: [
{text: "5", correct: true},
{text: "1", correct: false},
{text: "2", correct: false},
{text: "100", correct: false},
]
},
];

18
src/js/thirdperson.js Normal file
View File

@ -0,0 +1,18 @@
const hero = document.getElementById('hero');
const boss = document.getElementById('boss');
boss.style.transition = '2s cubic-bezier(0.4, 0, 0.2, 1)';
hero.style.transition = '2s cubic-bezier(0.4, 0, 0.2, 1)';
setTimeout(() => {
hero.style.left = '1000px';
}, 500);
setTimeout(()=> {
hero.src = "/assets/Design/KnightPixLE2-exporgift.gif";
}, 1700);
setTimeout(()=> {
window.location.href = "/game/loading.html"
}, 3000)

115
src/leaderboard.php Normal file
View File

@ -0,0 +1,115 @@
<?php
session_start();
require_once "config/db.php";
$sql= "SELECT username, score
FROM users
ORDER BY score DESC
LIMIT 8";
$nama = $_SESSION['username'];
$score = 0;
$getscore = "SELECT score FROM users WHERE username ='$nama'";
$result_me = mysqli_query($db,$getscore);
if ($result_me && mysqli_num_rows($result_me)>0){
$row = mysqli_fetch_assoc($result_me);
$score = $row['score'];
}
$queryrank = "SELECT COUNT(*) as ranking FROM users WHERE score > $score";
$resultrank = mysqli_query($db, $queryrank);
$rowrank = mysqli_fetch_assoc($resultrank);
$realrank = $rowrank['ranking']+1;
$result = mysqli_query($db, $sql);
$leaderboard = [];
if($result){
$leaderboard = mysqli_fetch_all($result, MYSQLI_ASSOC);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>leaderboard</title>
<link rel="stylesheet" href="css/global.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<audio id="bgm" src="/assets/music/leaderboard.mp3" loop autoplay></audio>
<div class="container-board">
<a class="back" href="onboard.php" data-aos="fade-in" data-aos-duration="3000"></a>
<div class="chara">
<div class="character">
<h1 style="text-align: center; padding-right: 45px; color: yellow;">Knight</h1>
<img src="/assets/Design/KnightPixLE2-exporgift.gif" alt="knight">
</div>
</div>
<div class="board">
<table>
<thead>
<tr>
<th>#</th>
<th>Username</th>
<th>Score</th>
</tr>
</thead>
<tbody>
<?php
$peringkat = 1;
if (!empty($leaderboard)) {
foreach ($leaderboard as $pemain) :
?>
<tr>
<td><?php echo $peringkat; ?></td>
<td><?php echo htmlspecialchars($pemain['username']); ?></td>
<td><?php echo $pemain['score']; ?> PTS</td>
</tr>
<?php
$peringkat++;
endforeach;
} else {
// Jika data kosong
echo '<tr><td colspan="3" style="text-align: center;">Belum ada pemain</td></tr>';
}
?>
</tbody>
<tbody>
<?php
$peringkat = 1;
?>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><?php echo $realrank; ?></td>
<td><?php echo $nama; ?></td>
<td><?php echo $score; ?> PTS</td>
</tr>
</tbody>
</table>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
const bgm = document.getElementById("bgm");
bgm.loop = true
bgm.volume = 0.2
bgm.play()
});
</script>
</body>
</html>

11
src/logout.php Normal file
View File

@ -0,0 +1,11 @@
<?php
session_start();
unset($_SESSION['loggedin']);
unset($_SESSION['username']);
unset($_SESSION['id']);
$_SESSION['flash'] = "Logout berhasil!";
header("Location: index.php");
exit();

40
src/notif.php Normal file
View File

@ -0,0 +1,40 @@
<div id="notif" class="notif"></div>
<style>
.notif {
position: fixed;
top: 50px;
left: 50%;
transform: translateX(-50%);
background-color: #b2db0e1c;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
color: yellow;
padding: 12px 18px;
width: 300px;
height: 25px;
font-size: 20px;
border: 1px solid yellow;
border-radius: 8px;
opacity: 0;
transition: .3s;
z-index: 9999;
}
.notif.show {
opacity: 1;
}
</style>
<script>
function showNotif(msg) {
const n = document.getElementById("notif");
n.textContent = msg;
n.classList.add("show");
setTimeout(() => {
n.classList.remove("show");
}, 3000);
}
</script>

72
src/onboard.php Normal file
View File

@ -0,0 +1,72 @@
<?php
session_start();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>onboard</title>
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<link rel="stylesheet" href="css/global.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<audio id="bgm" src="/assets/music/onboard.mp3" loop autoplay></audio>
<audio id="hover-sfx" src="/assets/music/hover.mp3" ></audio>
<div class="container-onboard">
<?php include 'notif.php'; ?>
<?php
if (!empty($_SESSION['flash'])) {
echo "<script>showNotif(" . json_encode($_SESSION['flash']) . ");</script>";
unset($_SESSION['flash']);
}
?>
<h1 data-aos="zoom-out" data-aos-duration="1000">👾 codebeater 👾</h1>
<div class="menu">
<a class="hover-btn" data-aos="zoom-out" data-aos-duration="2000" href="game/thirdperson.html">Game Start</a>
<a class="hover-btn" data-aos="zoom-out" data-aos-duration="2000" href="leaderboard.php">leaderboard</a>
<a class="hover-btn" data-aos="zoom-out" data-aos-duration="2000" href="credit.html">Credit</a>
<a class="hover-btn" data-aos="zoom-out" data-aos-duration="2000" href="logout.php">Exit</a>
</div>
</div>
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<script>
AOS.init();
</script>
<script>
document.addEventListener("DOMContentLoaded", () => {
const bgm = document.getElementById("bgm");
const hoversfx = document.getElementById('hover-sfx');
const buttons = document.querySelectorAll('.hover-btn');
bgm.volume =0.2;
hoversfx.volume =0.2;
buttons.forEach(button => {
button.addEventListener('mouseenter', () => {
hoversfx.currentTime = 0;
hoversfx.play().catch(error => console.log('menunggu iteraksi user'))
});
});
function playBGM(){
bgm.play().then(()=>{
console.log('BGM Berputar')
}).catch(error => {
console.log('auto diblok')
});
}
playBGM();
document.body.addEventListener("click", () => {
if (bgm.paused) {
bgm.play();
}
}, { once: true });
});
</script>
</body>
</html>

87
src/register.php Normal file
View File

@ -0,0 +1,87 @@
<?php
session_start();
include "config/db.php";
$pesan_sukses="";
$pesan_gagal="";
if(isset($_POST['register'])){
$email = $_POST['email'];
$username = $_POST['username'];
$password = $_POST['password'];
$rpassword = $_POST['rpassword'];
if(empty($email) || empty($username) || empty($password)){
$_SESSION['flash'] = "Semua data harus terisi";
}else if($password !== $rpassword){
$_SESSION['flash']= "password tidak sama";
}
else{
$hashpw = password_hash($password, PASSWORD_DEFAULT);
$sql = "INSERT INTO users (email,username,password,score)VALUES(?,?,?,0)";
$stmt = $db -> prepare($sql);
$stmt->bind_param("sss",$email,$username,$hashpw);
if($stmt->execute()){
header("location:index.php");
exit();
}else{
if($stmt->erno==1602){
$_SESSION['flash'] = "email atau username sudah pernah terdaftar";
}else{
$_SESSION['flash'] = "Regitrasi gagal: ".$stmt->error;
}
}
$stmt -> close();
}
}$db->close()
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>codebeater</title>
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<link rel="stylesheet" href="css/global.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container-register">
<?php
include "notif.php";
if (isset($_SESSION['flash'])) {
echo "<script>showNotif(" . json_encode($_SESSION['flash']) . ");</script>";
unset($_SESSION['flash']);
}
?>
<h1 data-aos="zoom-out" data-aos-duration="1000">codebeater</h1>
<form action="register.php" method="POST">
<h2 data-aos="fade-up" data-aos-duration="1000">Register to get account</h2>
<input type="email" name="email" id="email" placeholder="input your email" data-aos="fade-up" data-aos-duration="2000"><br>
<input type="text" name="username" id="username" placeholder="input your username" data-aos="fade-up" data-aos-duration="2000"><br>
<input type="password" name="password" id="password" placeholder="input your password" data-aos="fade-up" data-aos-duration="2000"><br>
<input type="password" name="rpassword" id="rpassword" placeholder="repeat your password" data-aos="fade-up" data-aos-duration="2000"><br>
<button type="submit" name="register" data-aos="fade-up" data-aos-duration="3000">REGISTER</button>
<p data-aos="fade-up" data-aos-duration="3000"><a href="index.php" name = "login">have an account? <span> Login now!</span></a></p>
</form>
</div>
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<script>
AOS.init();
</script>
</body>
</html>

38
src/score.php Normal file
View File

@ -0,0 +1,38 @@
<?php
session_start();
header("Content-Type: application/json");
require_once "config/db.php";
$data = json_decode(file_get_contents("php://input"), true);
if (!isset($data['score'])) {
echo json_encode(["error" => "score missing"]);
exit;
}
$score = (int)$data['score'];
$user_id = isset($_SESSION['id']) ? (int)$_SESSION['id'] : null;
if (!$user_id) {
echo json_encode(["error" => "no session user"]);
exit;
}
$sql = "UPDATE users SET score = score + ? where id =? ";
$stmt = $db ->prepare($sql);
if ($stmt){
$stmt->bind_param("ii",$score,$user_id);
if($stmt->execute()){
echo json_encode(["success" => true, "message" => "Score accumulated"]);
}else{
echo json_encode(["error" => "update failed: " . $stmt->error]);
}
$stmt->close();
}else{
echo json_encode(["error" => "stetment prep failed"]);
}
$db->close();
?>

80
users.sql Normal file
View File

@ -0,0 +1,80 @@
-- phpMyAdmin SQL Dump
-- version 5.2.3
-- https://www.phpmyadmin.net/
--
-- Host: db:3306
-- Generation Time: Dec 01, 2025 at 08:08 AM
-- Server version: 8.0.44
-- PHP Version: 8.3.26
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `codebeater`
--
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE `users` (
`id` int NOT NULL,
`username` varchar(50) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL,
`score` int NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `username`, `email`, `password`, `score`) VALUES
(1, 'bram', 'bahlil@gmail.com', '$2y$10$tOKCS5lO0/lRUW9c.VmsAeMu1M5LxO9F2lq/44yLk3Dl7FvmFUWEu', 100),
(4, 'bahlil', 'bahlil1@gmail.com', '$2y$10$qmU02E22qB6MD5RR8Bopi.nBI38jk2mOht2SHnXb64m30fpyg8cf6', 0),
(8, 'fork', 'bolo@gmail.com', '$2y$10$XZ/uNqSGiZhfCjDEaZUzner0L2tKRBrEVX5cNG0nK4f/IFuf42jCK', 0),
(13, 'adsasd', 'da@gmail.com', '$2y$10$lOWJD1OLc9/pREEvH72b4u7YDZpekwX9W/Wt7mlhSnJuhKNC2dm1i', 0),
(20, 'bobi', 'skibidi@gmail.com', '$2y$10$v2SToxPT3kzfD1BPMJuQGe2kOKqaX7ZcHyuvyUaAWm/GySx2RaAqW', 0),
(21, 'sada', 'sad@gmail.com', '$2y$10$JO0oMbKmJHbUhRNCcyYxnOwK0OFLv69FCItzwCK0h0p6KeAzvekGW', 0),
(24, 'orgil', 'fasfa@gmail.com', '$2y$10$rxkVaEwirysMIiaDgrixQeCbuGpkMdbvA2Kvw.l2t0hk7PO4KzZ4i', 0),
(28, 'bencong', 'bahliltod@gmai.com', '$2y$10$yM13E5kcWDU.FPUpuWkWbuGqpq9tMfS2vKE1Wu8xMPbHleNSCI5pW', 0),
(29, 'adudu', 'adudu@gmail.com', '$2y$10$MW5hI5zKBNDHpEgGOipozOVPaH985N0.J1qxHen15eK1KVI6HfKa.', 0),
(30, 'kkhungke', 'cuki@gmail.com', '$2y$10$6u2vzf6icHzmZeIqDfBHqOEwjGEcpuo0c7QGmZeuzICq71Af0vY6y', 0),
(33, 'koko', 'kkhungke@gmail.com', '$2y$10$ys7rs4PAtl0z74RfgNuu9O50t.ibMgljWEC8x.9Anm3DBw5aB7q8C', 0);
--
-- Indexes for dumped tables
--
--
-- Indexes for table `users`
--
ALTER TABLE `users`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `username` (`username`),
ADD UNIQUE KEY `email` (`email`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=34;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;