top 10
This commit is contained in:
parent
bfe422bbdd
commit
5de5f03b3c
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
db_info.txt
|
||||
db_connect.php
|
||||
|
112
css/style.css
112
css/style.css
@ -17,7 +17,7 @@
|
||||
* {
|
||||
color: white;
|
||||
font-family: 'Share Tech';
|
||||
font-size: 1em;
|
||||
font-size: 3vmin;
|
||||
}
|
||||
|
||||
body {
|
||||
@ -27,9 +27,9 @@ body {
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 50px;
|
||||
margin: 20px;
|
||||
text-shadow: 3px 2px rgb(153, 145, 175);
|
||||
font-size: 5vmin;
|
||||
margin: 2vmin;
|
||||
text-shadow: 3px 2px rgba(153, 145, 175, 0.5);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@ -56,60 +56,84 @@ a:active {
|
||||
#actions {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-gap: 20px;
|
||||
margin: 40px auto;
|
||||
width: 550px;
|
||||
grid-gap: 2vmin;
|
||||
margin: 4vmin auto;
|
||||
width: 100vmin;
|
||||
justify-items: left;
|
||||
}
|
||||
|
||||
#play {
|
||||
#button-link {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
margin: 30px;
|
||||
margin: 3vmin;
|
||||
}
|
||||
|
||||
#grid {
|
||||
#container {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: 120px 200px 120px;
|
||||
grid-gap: 20px;
|
||||
width: 72vmin;
|
||||
grid-template-columns: 18vmin 30vmin 18vmin;
|
||||
grid-gap: 3vmin;
|
||||
margin: auto;
|
||||
width: 480px;
|
||||
}
|
||||
|
||||
table {
|
||||
table-layout: fixed;
|
||||
border-spacing: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
td {
|
||||
th {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1px solid transparent;
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-style: outset;
|
||||
}
|
||||
|
||||
#hold {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
width: 18vmin;
|
||||
height: 18vmin;
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
#matrix {
|
||||
grid-column: 2;
|
||||
grid-row: 1 / 3;
|
||||
width: 200px;
|
||||
height: 480px;
|
||||
width: 30vmin;
|
||||
height: 72vmin;
|
||||
}
|
||||
|
||||
#next {
|
||||
grid-column: 3;
|
||||
grid-row: 1 / 3;
|
||||
width: 120px;
|
||||
height: 480px;
|
||||
width: 18vmin;
|
||||
height: 72vmin;
|
||||
}
|
||||
|
||||
#stats {
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
height: 0;
|
||||
width: 18vmin;
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-family: 'Share Tech';
|
||||
text-align: left;
|
||||
font-size: 2.5vmin;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-family: 'Share Tech Mono';
|
||||
text-align: right;
|
||||
font-size: 2.5vmin;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.invisible-row {
|
||||
@ -119,17 +143,17 @@ td {
|
||||
|
||||
.visible-row {
|
||||
background-color: transparent;
|
||||
border-color: rgba(128, 128, 128, 0.5);
|
||||
border-color: rgba(128, 128, 128, 0.3);
|
||||
border-style: inset;
|
||||
}
|
||||
|
||||
.tetromino-I {
|
||||
background-color: rgb(153, 255, 255);
|
||||
background-color: rgb(153, 255, 230);
|
||||
border-color: white;
|
||||
}
|
||||
|
||||
.tetromino-J {
|
||||
background-color: rgb(153, 255, 255);
|
||||
background-color: rgb(153, 204, 255);
|
||||
border-color: white;
|
||||
}
|
||||
|
||||
@ -179,31 +203,29 @@ td {
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
#stats {
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
height: 0;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-family: 'Share Tech';
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-family: 'Share Tech Mono';
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#message {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: white;
|
||||
font-size: 19px;
|
||||
font-size: 3vmin;
|
||||
text-shadow: 1px 1px black;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#leaderboard {
|
||||
min-width: 25%;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
border-top: 1px solid white;
|
||||
caption-side: top;
|
||||
}
|
||||
|
||||
.player {
|
||||
font-family: 'Share Tech';
|
||||
text-align: center;
|
||||
font-size: 2.5vmin;
|
||||
color: white;
|
||||
}
|
49
index.php
49
index.php
@ -5,31 +5,42 @@
|
||||
<title>Webtris</title>
|
||||
<link rel="icon" type="image/png" href="favicon.png">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css" />
|
||||
<script type="text/javascript" src="js/index.js"></script>
|
||||
<script type="text/javascript" src="js/webtris.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>WEBTRIS</h1>
|
||||
<div id="actions">
|
||||
<div id="container">
|
||||
<?php
|
||||
function addButton($action, $label) {
|
||||
?>
|
||||
<div><?=$label?></div>
|
||||
<button type="button" onclick="changeKey(this, '<?=$action?>')">
|
||||
<script>getKey("<?=$action?>")</script>
|
||||
</button>
|
||||
<?php }
|
||||
addButton("moveLeft", "GAUCHE");
|
||||
addButton("moveRight", "DROITE");
|
||||
addButton("softDrop", "CHUTE LENTE");
|
||||
addButton("hardDrop", "CHUTE RAPIDE");
|
||||
addButton("rotateCW", "ROTATION HORAIRE");
|
||||
addButton("rotateCCW", "ROTATE INVERSE");
|
||||
addButton("hold", "GARDE");
|
||||
addButton("pause", "PAUSE");
|
||||
function echoTable($id, $rows, $columns) {
|
||||
echo " <table id='$id'>\n";
|
||||
for ($y = 0; $y < $rows; $y++) {
|
||||
echo " <tr>";
|
||||
for ($x = 0; $x < $columns; $x++) {
|
||||
echo "<td></td>";
|
||||
}
|
||||
echo "</tr>\n";
|
||||
}
|
||||
echo " </table>\n";
|
||||
}
|
||||
echoTable("hold", 6, 6);
|
||||
echoTable("matrix", 24, 10);
|
||||
echoTable("next", 24, 6);
|
||||
?>
|
||||
<table id="stats">
|
||||
<tr><th class="name">SCORE</th><td class="value" id="score">0</td></tr>
|
||||
<tr><th class="name">RECORD</th><td class="value" id="highScore">0</td></tr>
|
||||
<tr><th class="name">TEMPS</th><td class="value" id="time">00:00</td></tr>
|
||||
<tr><th class="name">NIVEAU</th><td class="value" id="level">0</td></tr>
|
||||
<tr><th class="name">OBJECTIF</th><td class="value" id="goal">0</td></tr>
|
||||
<tr><th class="name">LIGNES</th><td class="value" id="clearedLines">0</td></tr>
|
||||
</table>
|
||||
<div id="message"></div>
|
||||
</div>
|
||||
<div id="play">
|
||||
<a href="webtris.php">JOUER</a>
|
||||
<div id="button-link">
|
||||
<a href="options.php" target="_blank">OPTIONS</a>
|
||||
</div>
|
||||
<div id="button-link">
|
||||
<a href="index.php">REJOUER</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
20
intop10.php
Normal file
20
intop10.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
include "db_connect.php";
|
||||
if (isset($_POST['score'])) {
|
||||
try {
|
||||
$db = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=utf8", $DB_USER, $DB_PASSWORD);
|
||||
} catch (Exception $e) {
|
||||
die('Erreur : ' . $e->getMessage());
|
||||
}
|
||||
$query = $db->prepare('SELECT player, score FROM `leaderboard` ORDER BY score DESC LIMIT 10;');
|
||||
$entryScore = $query->fetch();
|
||||
$query->closeCursor();
|
||||
$score = (int) $_POST['score'];
|
||||
if ($score > $entryScore)
|
||||
echo "true";
|
||||
else
|
||||
echo "false";
|
||||
} else {
|
||||
header($_SERVER["SERVER_PROTOCOL"] . " 405 Method Not Allowed", true, 405);
|
||||
}
|
||||
?>
|
@ -86,6 +86,7 @@ const actionsDefaultKeys = {
|
||||
hold: "c",
|
||||
pause: "Escape",
|
||||
}
|
||||
const RETRIES = 3
|
||||
var actions = {}
|
||||
|
||||
|
||||
@ -442,15 +443,10 @@ function fallingPhase() {
|
||||
}
|
||||
|
||||
function lockPhase() {
|
||||
if (!move(MOVEMENT.DOWN)) {
|
||||
matrix.piece.locked = true
|
||||
if (!scheduler.timeoutTasks.has(lockDown))
|
||||
scheduler.setTimeout(lockDown, stats.lockDelay)
|
||||
matrix.draw()
|
||||
}
|
||||
move(MOVEMENT.DOWN)
|
||||
}
|
||||
|
||||
function move(movement, testMinoesPos=matrix.piece.minoesPos) {
|
||||
function move(movement, testMinoesPos=matrix.piece.minoesPos, hardDrop=false) {
|
||||
const testPos = matrix.piece.pos.add(movement)
|
||||
if (matrix.spaceToMove(testMinoesPos.translate(testPos))) {
|
||||
matrix.piece.pos = testPos
|
||||
@ -459,14 +455,21 @@ function move(movement, testMinoesPos=matrix.piece.minoesPos) {
|
||||
matrix.piece.rotatedLast = false
|
||||
if (matrix.spaceToMove(matrix.piece.minoesPos.translate(matrix.piece.pos.add(MOVEMENT.DOWN))))
|
||||
fallingPhase()
|
||||
else {
|
||||
else if (!hardDrop) {
|
||||
matrix.piece.locked = true
|
||||
scheduler.clearTimeout(lockDown)
|
||||
scheduler.setTimeout(lockDown, stats.lockDelay)
|
||||
}
|
||||
if (!hardDrop)
|
||||
matrix.draw()
|
||||
return true
|
||||
} else {
|
||||
if (movement == MOVEMENT.DOWN) {
|
||||
matrix.piece.locked = true
|
||||
if (!scheduler.timeoutTasks.has(lockDown))
|
||||
scheduler.setTimeout(lockDown, stats.lockDelay)
|
||||
matrix.draw()
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -489,9 +492,11 @@ function rotate(spin) {
|
||||
|
||||
function lockDown(){
|
||||
scheduler.clearInterval(lockPhase)
|
||||
if (matrix.piece.minoesAbsPos.every(pos => pos.y < MATRIX_INVISIBLE_ROWS))
|
||||
game_over()
|
||||
else {
|
||||
if (matrix.piece.minoesAbsPos.every(pos => pos[1] < MATRIX_INVISIBLE_ROWS)) {
|
||||
matrix.piece.locked = false
|
||||
matrix.draw()
|
||||
gameOver()
|
||||
} else {
|
||||
matrix.piece.minoesAbsPos.forEach(pos => matrix.lockedMinoes[pos[1]][pos[0]] = matrix.piece.shape)
|
||||
|
||||
// T-Spin detection
|
||||
@ -541,10 +546,48 @@ function gameOver() {
|
||||
scheduler.clearTimeout(lockDown)
|
||||
scheduler.clearInterval(clock)
|
||||
|
||||
var info = `GAME OVER\nScore : ${stats.score}`
|
||||
if (stats.score == stats.highScore) {
|
||||
alert("Bravo !\nVous avez battu votre précédent record.")
|
||||
localStorage.setItem('highScore', stats.highScore)
|
||||
info += "\nBravo ! Vous avez battu votre précédent record."
|
||||
} else
|
||||
var info = `GAME OVER\nScore : ${stats.score}`
|
||||
|
||||
var XHR = new XMLHttpRequest()
|
||||
var FD = new FormData()
|
||||
FD.append("score", stats.score)
|
||||
XHR.addEventListener('load', function(event) {
|
||||
if (event.target.responseText == "true") {
|
||||
var player = prompt(info + "\nBravo ! Vous êtes dans le Top 10.\nEntrez votre nom pour publier votre score :" , localStorage.getItem("name") || "")
|
||||
if (player.length) {
|
||||
localStorage.setItem("player", player)
|
||||
postScore(player, stats.score)
|
||||
}
|
||||
} else {
|
||||
alert(info)
|
||||
}
|
||||
})
|
||||
XHR.addEventListener('error', function(event) {
|
||||
alert(info)
|
||||
})
|
||||
XHR.open('POST', 'intop10.php')
|
||||
XHR.send(FD)
|
||||
}
|
||||
|
||||
function postScore(player, score) {
|
||||
var XHR = new XMLHttpRequest()
|
||||
var FD = new FormData()
|
||||
FD.append("player", player)
|
||||
FD.append("score", stats.score)
|
||||
XHR.addEventListener('load', function(event) {
|
||||
open("leaderboard.php")
|
||||
})
|
||||
XHR.addEventListener('error', function(event) {
|
||||
if (confirm('Erreur de connexion.\nRéessayer ?'))
|
||||
postScore(player, score)
|
||||
})
|
||||
XHR.open('POST', 'publish.php')
|
||||
XHR.send(FD)
|
||||
}
|
||||
|
||||
function autorepeat() {
|
||||
@ -615,7 +658,8 @@ function hardDrop() {
|
||||
for (matrix.trail.height = 0; move(MOVEMENT.DOWN); matrix.trail.height++) {
|
||||
stats.score += 2
|
||||
}
|
||||
while (move(MOVEMENT.DOWN)) {}
|
||||
while (move(MOVEMENT.DOWN, matrix.piece.minoesPos, true)) {}
|
||||
matrix.draw()
|
||||
lockDown()
|
||||
scheduler.setTimeout(clearTrail, ANIMATION_DELAY)
|
||||
}
|
||||
@ -655,9 +699,9 @@ function pause() {
|
||||
scheduler.clearTimeout(lockDown)
|
||||
scheduler.clearTimeout(autorepeat)
|
||||
scheduler.clearInterval(clock)
|
||||
hold.draw()
|
||||
holdQueue.draw()
|
||||
matrix.draw()
|
||||
next.draw()
|
||||
nextQueue.draw()
|
||||
}
|
||||
|
||||
function resume() {
|
||||
|
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Webtris</title>
|
||||
<link rel="icon" type="image/png" href="favicon.png">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>WEBTRIS</h1>
|
||||
<table id="leaderboard">
|
||||
<caption>MEILLEURS SCORES</caption>
|
||||
<?php
|
||||
include "db_connect.php";
|
||||
try {
|
||||
$db = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=utf8", $DB_USER, $DB_PASSWORD);
|
||||
} catch (Exception $e) {
|
||||
die('Erreur : ' . $e->getMessage());
|
||||
}
|
||||
$top10 = $db->query('SELECT player, score FROM `leaderboard` ORDER BY score DESC LIMIT 10;');
|
||||
for ($i = 1; $row = $top10->fetch(); $i++) {
|
||||
echo ' <tr><th class="name">' . $i . '<td class="player">' . $row['player'] . '</td><td class="value">' . $row['score'] . "</td></tr>\n";
|
||||
}
|
||||
$top10->closeCursor();
|
||||
?>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
32
options.php
Normal file
32
options.php
Normal file
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Webtris</title>
|
||||
<link rel="icon" type="image/png" href="favicon.png">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css" />
|
||||
<script type="text/javascript" src="js/index.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>WEBTRIS</h1>
|
||||
<div id="actions">
|
||||
<?php
|
||||
function addButton($action, $label) {
|
||||
?>
|
||||
<div><?=$label?></div>
|
||||
<button type="button" onclick="changeKey(this, '<?=$action?>')">
|
||||
<script>getKey("<?=$action?>")</script>
|
||||
</button>
|
||||
<?php }
|
||||
addButton("moveLeft", "GAUCHE");
|
||||
addButton("moveRight", "DROITE");
|
||||
addButton("softDrop", "CHUTE LENTE");
|
||||
addButton("hardDrop", "CHUTE RAPIDE");
|
||||
addButton("rotateCW", "ROTATION HORAIRE");
|
||||
addButton("rotateCCW", "ROTATE INVERSE");
|
||||
addButton("hold", "GARDE");
|
||||
addButton("pause", "PAUSE");
|
||||
?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
14
publish.php
Normal file
14
publish.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include "db_connect.php";
|
||||
if (isset($_POST['player']) && isset($_POST['score'])) {
|
||||
try {
|
||||
$db = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=utf8", $DB_USER, $DB_PASSWORD);
|
||||
} catch (Exception $e) {
|
||||
die('Erreur : ' . $e->getMessage());
|
||||
}
|
||||
$query = $db->prepare('INSERT INTO `leaderboard` (`player`, `score`) VALUES (:player, :score);');
|
||||
$query->execute(array("player" => strip_tags($_POST['player']), "score" => (int) $_POST['score']));
|
||||
} else {
|
||||
header($_SERVER["SERVER_PROTOCOL"] . " 405 Method Not Allowed", true, 405);
|
||||
}
|
||||
?>
|
47
webtris.php
47
webtris.php
@ -1,47 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Webtris</title>
|
||||
<link rel="icon" type="image/png" href="favicon.png">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css" />
|
||||
<script type="text/javascript" src="js/webtris.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>WEBTRIS</h1>
|
||||
<div id="grid">
|
||||
<?php
|
||||
function echoTable($id, $rows, $columns) {
|
||||
echo " <table id='$id'>\n";
|
||||
echo " <tbody>\n";
|
||||
for ($y = 0; $y < $rows; $y++) {
|
||||
echo " <tr>";
|
||||
for ($x = 0; $x < $columns; $x++) {
|
||||
echo "<td></td>";
|
||||
}
|
||||
echo "</tr>\n";
|
||||
}
|
||||
echo " </tbody>\n";
|
||||
echo " </table>\n";
|
||||
}
|
||||
echoTable("hold", 6, 6);
|
||||
echoTable("matrix", 24, 10);
|
||||
echoTable("next", 24, 6);
|
||||
?>
|
||||
<table id="stats">
|
||||
<tbody>
|
||||
<tr><td class="stat-label">SCORE</td><td class="stat-value" id="score">0</td></tr>
|
||||
<tr><td class="stat-label">RECORD</td><td class="stat-value" id="highScore">0</td></tr>
|
||||
<tr><td class="stat-label">TEMPS</td><td class="stat-value" id="time">00:00</td></tr>
|
||||
<tr><td class="stat-label">NIVEAU</td><td class="stat-value" id="level">0</td></tr>
|
||||
<tr><td class="stat-label">OBJECTIF</td><td class="stat-value" id="goal">0</td></tr>
|
||||
<tr><td class="stat-label">LIGNES</td><td class="stat-value" id="clearedLines">0</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="message"></div>
|
||||
</div>
|
||||
<div id="play">
|
||||
<a href="webtris.html">REJOUER</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
51
webtris.sql
Normal file
51
webtris.sql
Normal file
@ -0,0 +1,51 @@
|
||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||
SET AUTOCOMMIT = 0;
|
||||
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: `webtris`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `leaderboard`
|
||||
--
|
||||
|
||||
CREATE TABLE `leaderboard` (
|
||||
`id` int(11) NOT NULL,
|
||||
`player` varchar(20) NOT NULL,
|
||||
`score` int(11) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Indexes for dumped tables
|
||||
--
|
||||
|
||||
--
|
||||
-- Indexes for table `leaderboard`
|
||||
--
|
||||
ALTER TABLE `leaderboard`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT for dumped tables
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT for table `leaderboard`
|
||||
--
|
||||
ALTER TABLE `leaderboard`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||
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 */;
|
Reference in New Issue
Block a user