This commit is contained in:
Adrien MALINGREY 2019-11-01 02:39:44 +01:00
parent bfe422bbdd
commit 5de5f03b3c
10 changed files with 304 additions and 129 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
db_info.txt
db_connect.php

View File

@ -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;
}

View File

@ -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
View 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);
}
?>

View File

@ -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() {

View File

@ -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
View 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
View 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);
}
?>

View File

@ -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
View 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 */;