implement basic game mechanics
BIN
potain05/assets/icons/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
potain05/assets/icons/android-chrome-256x256.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
potain05/assets/icons/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
9
potain05/assets/icons/browserconfig.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/icons/mstile-150x150.png?v=potain"/>
|
||||
<TileColor>#da532c</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
BIN
potain05/assets/icons/favicon-16x16.png
Normal file
After Width: | Height: | Size: 724 B |
BIN
potain05/assets/icons/favicon-32x32.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
potain05/assets/icons/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
potain05/assets/icons/mstile-150x150.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
29
potain05/assets/icons/safari-pinned-tab.svg
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="256.000000pt" height="256.000000pt" viewBox="0 0 256.000000 256.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,256.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1515 2548 c-2 -7 -5 -24 -7 -38 -3 -22 -61 -50 -638 -307 -485 -216
|
||||
-645 -283 -675 -283 -37 0 -47 -7 -118 -78 -72 -72 -77 -80 -77 -120 l0 -42
|
||||
80 0 80 0 0 -280 0 -280 -40 0 -40 0 0 -160 0 -160 36 0 35 0 -35 -34 c-32
|
||||
-30 -36 -39 -36 -86 0 -46 4 -56 34 -86 30 -30 40 -34 86 -34 46 0 56 4 86 34
|
||||
21 21 34 44 34 60 0 24 -3 26 -45 26 -32 0 -45 -4 -45 -14 0 -7 -8 -16 -17
|
||||
-18 -53 -14 -58 32 -8 78 19 17 35 41 35 53 0 18 6 21 40 21 l40 0 0 160 0
|
||||
160 -40 0 -40 0 0 280 0 280 520 0 520 0 0 -98 c0 -90 2 -100 23 -120 18 -17
|
||||
36 -22 80 -22 l57 0 0 -640 0 -640 -160 0 -160 0 0 -80 0 -80 480 0 480 0 0
|
||||
80 0 80 -160 0 -160 0 0 640 c0 613 1 640 18 640 10 0 28 10 40 23 19 21 22
|
||||
34 22 120 l0 97 80 0 80 0 0 -80 0 -80 280 0 280 0 0 240 0 240 -113 0 -113 0
|
||||
-316 230 c-320 232 -328 240 -328 303 l0 27 -85 0 c-60 0 -87 -4 -90 -12z
|
||||
m-25 -175 c0 -5 -9 -66 -20 -138 -11 -71 -20 -136 -20 -142 0 -8 -12 -13 -29
|
||||
-13 -55 0 -141 -83 -141 -136 l0 -24 -412 1 c-325 0 -408 3 -388 12 61 30 996
|
||||
446 1003 446 4 1 7 -2 7 -6z m600 -371 l-90 -3 0 -39 0 -40 -80 0 -80 0 0 59
|
||||
c0 52 -3 62 -26 80 -15 12 -34 21 -44 21 -14 0 -20 20 -33 118 -10 64 -17 122
|
||||
-17 129 0 7 103 -63 230 -155 l230 -167 -90 -3z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
19
potain05/assets/icons/site.webmanifest
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "",
|
||||
"short_name": "",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/icons/android-chrome-192x192.png?v=potain",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/icons/android-chrome-256x256.png?v=potain",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
83
potain05/assets/jeu.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
"use strict";
|
||||
|
||||
const GAME_NOT_STARTED = 0;
|
||||
const GAME_STARTED = 1;
|
||||
const GAME_WON = 2;
|
||||
const GAME_LOST = 3;
|
||||
|
||||
let gameState = GAME_NOT_STARTED;
|
||||
|
||||
let zones = undefined;
|
||||
let endTimeout = undefined;
|
||||
let roundTimeout = undefined;
|
||||
let timeBetween = 2000;
|
||||
const MIN_TIME_BETWEEN = 1000;
|
||||
const ACCELERATION = 100;
|
||||
|
||||
(function () {
|
||||
zones = document.getElementsByClassName("zone");
|
||||
for (const zone of zones) {
|
||||
zone.addEventListener("click", event => {
|
||||
if (gameState !== GAME_STARTED) {
|
||||
return;
|
||||
}
|
||||
console.log(event.target.classList);
|
||||
if (event.target.classList.contains("inactive")) {
|
||||
gameState = GAME_LOST;
|
||||
end();
|
||||
} else {
|
||||
event.target.style.transition = "";
|
||||
event.target.classList.remove("fade-out");
|
||||
event.target.classList.add("inactive");
|
||||
}
|
||||
})
|
||||
}
|
||||
})();
|
||||
|
||||
function start() {
|
||||
console.log("start!");
|
||||
document.getElementsByTagName("button")[0].disabled = true;
|
||||
gameState = GAME_STARTED;
|
||||
endTimeout = setTimeout(end, 30_000);
|
||||
roundTimeout = setTimeout(round, 1);
|
||||
}
|
||||
|
||||
function round() {
|
||||
if (gameState !== GAME_STARTED) {
|
||||
end();
|
||||
return;
|
||||
}
|
||||
|
||||
let zone = zones[Math.floor(Math.random() * zones.length)];
|
||||
zone.classList.remove("inactive");
|
||||
setTimeout(function () {
|
||||
zone.style.transition = `background-color ${timeBetween}ms`;
|
||||
}, 100);
|
||||
setTimeout(function () {
|
||||
zone.classList.add("fade-out");
|
||||
}, MIN_TIME_BETWEEN / 2);
|
||||
let zoneTimeout = setTimeout(() => {
|
||||
if (!zone.classList.contains("inactive")) {
|
||||
console.log("lost because didn't click fast enough", zone.id);
|
||||
gameState = GAME_LOST;
|
||||
end();
|
||||
}
|
||||
}, timeBetween);
|
||||
zone.addEventListener("click", () => {clearTimeout(zoneTimeout)})
|
||||
|
||||
// Recursive call
|
||||
timeBetween -= ACCELERATION;
|
||||
if (timeBetween <= MIN_TIME_BETWEEN) {timeBetween = MIN_TIME_BETWEEN;}
|
||||
roundTimeout = setTimeout(round, timeBetween);
|
||||
}
|
||||
|
||||
function end() {
|
||||
clearTimeout(roundTimeout);
|
||||
clearTimeout(endTimeout);
|
||||
if (gameState === GAME_STARTED) {
|
||||
gameState = GAME_WON;
|
||||
document.getElementsByClassName("success stamp")[0].classList.remove("hidden");
|
||||
} else if (gameState === GAME_LOST) {
|
||||
document.getElementsByClassName("failure stamp")[0].classList.remove("hidden");
|
||||
}
|
||||
}
|
96
potain05/assets/style.css
Normal file
|
@ -0,0 +1,96 @@
|
|||
html {
|
||||
height:100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
}
|
||||
|
||||
header {
|
||||
background-color: rgb(40,53,131);
|
||||
color: white;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
main, footer {
|
||||
max-width: 1600px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.stamp {
|
||||
position: absolute;
|
||||
font-size: 60px;
|
||||
transform: rotate(-20deg);
|
||||
display: inline-block;
|
||||
padding: .2em .5em;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.success.stamp {
|
||||
top: 120px;
|
||||
left: 60px;
|
||||
color: #0f5132;
|
||||
background-color: #d1e7dd;
|
||||
border: 3px solid #859a99;
|
||||
}
|
||||
|
||||
.failure.stamp {
|
||||
/* TODO center the stamp */
|
||||
top: 120px;
|
||||
left: 60px;
|
||||
color: #510f0f;
|
||||
background-color: #e7d1d1;
|
||||
border: 3px solid #9a8585;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.failure {
|
||||
color: #a71717;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: green;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgb(40,53,131);
|
||||
}
|
||||
|
||||
.img-holder {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.img-holder .zone {
|
||||
position: absolute;
|
||||
display: block;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.img-holder .zone.inactive,
|
||||
.img-holder .zone.fade-out {
|
||||
background-color: transparent;
|
||||
}
|
BIN
potain05/images/fond.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
49
potain05/index.html
Normal file
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Potain de chantier #5</title>
|
||||
<link rel="stylesheet" href="assets/style.css">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/icons/apple-touch-icon.png?v=potain">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/icons/favicon-32x32.png?v=potain">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/icons/favicon-16x16.png?v=potain">
|
||||
<link rel="manifest" href="assets/icons/site.webmanifest?v=potain">
|
||||
<link rel="mask-icon" href="assets/icons/safari-pinned-tab.svg?v=potain" color="#5bbad5">
|
||||
<link rel="shortcut icon" href="assets/icons/favicon.ico?v=potain">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="msapplication-config" content="assets/icons/browserconfig.xml?v=potain">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<meta property="og:image" content="https://static.augendre.info/potain3/images/fond.png">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Potain de chantier #5</h1>
|
||||
</header>
|
||||
<main>
|
||||
<h2>Jeu interactif</h2>
|
||||
<p>
|
||||
Aide Pimpin le technicien à reboucher les fuites ! <br>
|
||||
<button onclick="start()">Commencer</button>
|
||||
</p>
|
||||
<div class="img-holder">
|
||||
<img src="images/fond.png" width="727" height="330" alt="Plan Cecolyon">
|
||||
<div id="bureau-1" class="zone inactive" style="width:50px; height: 50px; top: 0; left: 0;"></div>
|
||||
<div id="bureau-2" class="zone inactive" style="width:50px; height: 50px; top: 55px; left: 0;"></div>
|
||||
<div id="bureau-3" class="zone inactive" style="width:50px; height: 50px; top: 0; left: 55px;"></div>
|
||||
<div id="bureau-4" class="zone inactive" style="width:50px; height: 50px; top: 55px; left: 55px;"></div>
|
||||
<span class="success stamp hidden">FÉLICITATIONS 🎉</span>
|
||||
<span class="failure stamp hidden">PERDU 😞</span>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
<p>
|
||||
Made with ♥ by <a href="https://gabnotes.org/about-me/">Gabriel Augendre</a>.
|
||||
Ce programme est un <a href="https://fr.wikipedia.org/wiki/Logiciel_libre">logiciel libre</a>.
|
||||
<a href="https://git.augendre.info/gaugendre/potain">Code source</a>.
|
||||
</p>
|
||||
</footer>
|
||||
<script src="assets/jeu.js"></script>
|
||||
<!--<script data-goatcounter="https://static.gc.augendre.info/count"-->
|
||||
<!-- async src="https://static.gc.augendre.info/count.js"></script>-->
|
||||
</body>
|
||||
</html>
|