Cette révision appartient à :
Axel O 2022-12-12 17:20:26 +01:00
révision 109971f1d6
8 fichiers modifiés avec 246 ajouts et 48 suppressions

Voir le fichier

@ -22,32 +22,63 @@
<![endif]-->
<nav>
<h1>Sokoban</h1>
<ol id="level-list">
<ol id="level-list" class="not-in-win-animation">
</ol>
</nav>
<main>
<div class="controls">
<div class="container">
<aside class="left-sidebar">
<table border="1">
<thead>
<th>Name</th>
<th>Score</th>
</thead>
<tbody id="scoreTable">
<tr>
<td>
Axel
</td>
<td>1</td>
</tr>
<tr>
<td>
Ronan
</td>
<td>2</td>
</tr>
</tbody>
</table>
</aside>
<main>
<article class="not-in-win-animation">
<canvas id="canvas" width="800" height="400"></canvas>
<div id="tutorial-speech-bubble" class="text-bubble">
<div class="dialog">
<p id="tutorial-box" class="speech"></p>
<div class="right-point">
</div>
<div class="right-point shifted">
</div>
</div>
</div>
</article>
</main>
<aside class="controls not-in-win-animation right-sidebar">
<div id="timer">Time</div>
<button id="pause-1">Pause</button>
<button id="pause-2">Pause</button><br/>
<label for="dificulty-slider">Difficulty</label><br/>
<input type="range" min="0" max="100" value="50" id="difficulty-slider">
<br/>
</div>
<div>
<canvas id="canvas" width="800" height="400"></canvas>
<div id="tutorial-speech-bubble" class="text-bubble">
<div class="dialog">
<div class="left-point">
</div>
<div class="left-point shifted">
</div>
<p id="tutorial-box" class="speech"></p>
</div>
</div>
</div>
</aside>
</div>
</main>
<footer>
<p>Sokoban 2022</p>
<p>Pour une meilleure expérience, veuillez utiliser ce jeu sur un ordinateur avec un écran horizontal.</p>
</footer>
</body>
<!-- <script type="module" src="./modules/ressources.mjs"></script> -->

Voir le fichier

@ -2,6 +2,8 @@ import { levelsBlueprint } from '/modules/levels.mjs'
import { generatePlayground } from '/modules/playground.mjs'
import { Timer } from '/modules/timer.mjs'
const prionicSequence = [0, 2, 6, 12, 20, 30, 42];
export const selectLevel = (ctx, gameState, id) => {
gameState.playground = generatePlayground(levelsBlueprint[id].structure, gameState.width, gameState.height);
// TODO transfer expireFunction without a fail
@ -18,15 +20,37 @@ export const fillLevelsSelection = (gameState, ctx) => {
selectionButton.setAttribute("array-index", i);
selectionButton.addEventListener("click", (click) => {
selectLevel(ctx, gameState, click.srcElement.getAttribute("array-index"));
// let blueprint = levelsBlueprint[
// click.srcElement.getAttribute("array-index")
// ];
// gameState.playground = generatePlayground(blueprint.structure, gameState.width, gameState.height);
// gameState.timer = new Timer(blueprint.time, gameState.timer.expireFunction);
// gameState.playground.draw(ctx, gameState.width, gameState.height);
});
selectionButton.innerText = "Level" + i;
selectionButton.innerText = "Level " + prionicSequence[i];
listElement.appendChild(selectionButton);
levelList.appendChild(listElement);
}
}
export class LevelManager {
constructor(winFunction, StartingLevelId = 0) {
self.CurrentLevelId = StartingLevelId;
self.Completed = levelsBlueprint.map(() => { return false; });
self.winFunction = winFunction;
}
getFirstUncompleted() {
for( let i = 0; i < self.Completed.size; i++ ) {
if (!self.Completed[i]) {
return i;
}
}
}
next(ctx, gameState) {
self.Completed[self.CurrentLevelId] = true;
let allLevelsFinished = self.Completed.reduce((a, b) => {
return a && b;
}, true);
if (allLevelsFinished) {
self.winFunction();
}
self.CurrentLevelId = getFirstUncompleted();
selectLevel(ctx, gameState, self.CurrentLevelId);
}
}

Voir le fichier

@ -25,7 +25,57 @@ const level2Blueprint = {
time: 23000,
};
const level3Blueprint = {
structure: [
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall,],
[Square.Wall, Square.Floor, Square.Floor, Square.Floor, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall,],
[Square.Wall, Square.Floor, Square.Box, Square.Floor, Square.Destination, Square.Destination, Square.Destination, Square.Wall, Square.Wall, Square.Wall,],
[Square.Wall, Square.Wall, Square.Destination, Square.Box, Square.Box, Square.Destination, Square.Floor, Square.Floor, Square.Wall, Square.Wall,],
[Square.Wall, Square.Wall, Square.Destination, Square.Destination, Square.Floor, Square.Box, Square.Box, Square.Floor, Square.Wall, Square.Wall,],
[Square.Wall, Square.Wall, Square.Destination, Square.Box, Square.Box, Square.Floor, Square.Box, Square.Floor, Square.Floor, Square.Floor],
[Square.Wall, Square.Wall, Square.Player, Square.Destination, Square.Destination, Square.Box, Square.Box, Square.Floor, Square.Floor, Square.Wall,],
[Square.Wall, Square.Wall, Square.Floor, Square.Floor, Square.Floor, Square.Floor, Square.Floor, Square.Wall, Square.Wall, Square.Wall,],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall,],
],
time: 8000,
}
const level4Blueprint = {
structure: [
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall,],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Floor, Square.Floor, Square.Wall, Square.Wall, Square.Wall,],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Floor, Square.Box, Square.Wall, Square.Wall, Square.Wall,],
[Square.Wall, Square.Wall, Square.Destination, Square.Floor, Square.Floor, Square.Floor, Square.Floor, Square.Floor, Square.Wall, Square.Wall, Square.Wall,],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Floor, Square.Floor, Square.Box, Square.Floor, Square.Floor, Square.Destination, Square.Wall,],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Box, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall,],
[Square.Wall, Square.Floor, Square.Floor, Square.Wall, Square.Player, Square.Floor, Square.Box, Square.Floor, Square.Floor, Square.Destination, Square.Wall,],
[Square.Wall, Square.Floor, Square.Floor, Square.Floor, Square.Floor, Square.Floor, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall,],
[Square.Wall, Square.Destination, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall,],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall,],
],
time: 3000,
}
const level5Blueprint = {
structure: [
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, ],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Floor, Square.Floor, Square.Floor, Square.Floor, Square.Floor, Square.Player, Square.Wall, Square.Wall, ],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Floor, Square.Box, Square.Wall, Square.Box, Square.Floor, Square.Wall, Square.Wall, Square.Wall, ],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Floor, Square.Box, Square.Floor, Square.Floor, Square.Box, Square.Wall, Square.Wall, Square.Wall, ],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Box, Square.Floor, Square.Box, Square.Floor, Square.Wall, Square.Wall, Square.Wall, ],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Floor, Square.Box, Square.Floor, Square.Wall, Square.Floor, Square.Wall, Square.Wall, Square.Wall, ],
[Square.Wall, Square.Destination, Square.Destination, Square.Destination, Square.Destination, Square.Floor, Square.Floor, Square.Wall, Square.Wall, Square.Floor, Square.Box, Square.Floor, Square.Floor, Square.Box, Square.Floor, Square.Floor, Square.Wall, ],
[Square.Wall, Square.Wall, Square.Destination, Square.Destination, Square.Destination, Square.Floor, Square.Floor, Square.Floor, Square.Floor, Square.Box, Square.Floor, Square.Floor, Square.Box, Square.Floor, Square.Floor, Square.Floor, Square.Wall, ],
[Square.Wall, Square.Destination, Square.Destination, Square.Destination, Square.Floor, Square.Floor, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, ],
[Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, Square.Wall, ],
],
time: 40000
}
export const levelsBlueprint = [
level1Blueprint,
level2Blueprint,
]
level3Blueprint,
level4Blueprint,
level5Blueprint,
];

Voir le fichier

@ -2,8 +2,6 @@ export class Timer {
readDifficulty(slider) {
self.difficulty = 1.5 - slider.value * 0.01;
self.time = self.originalTime * self.difficulty;
console.log("difficulty: " + self.difficulty);
console.log("time: " + self.time);
}
constructor(time, expireFunction) {
@ -48,8 +46,8 @@ export class Timer {
if (self.timeRunning) {
let timeStr = String(self.time).padStart(5, '0');
self.timerElement.innerHTML = "Time : " + timeStr.slice(0, 3) + '.' + timeStr.slice(3);
if (self.time == 0) {
this.expireFunction();
if (self.time <= 0) {
self.expireFunction();
clearInterval(self.intervalControler);
self.timeRunning = false;
}

Voir le fichier

@ -1,6 +1,6 @@
export class TutorialControler {
static messages = [
"V'là le Jérome avec son tracteur.\nFaut vit qu'il les mettes sous l'toit avant que ça pleuve.",
"V'là le Jérome avec son tracteur.\nFaut vit qu'il les mettes sous l'toit avant que ça pleuve. (Appuye sur <Espace> pour continuer)",
"Je m'suis dit : \"Faudrait que je d'mandes que tu lui y fasse\"",
"Pi tant qu'à faire, c'pas dur. T'as qu'à appuyer sur les flèches",
"Ben qu'est qu't'attends ? Vas y!",

Voir le fichier

@ -1,7 +1,7 @@
import { generatePlayground } from '/modules/playground.mjs'
import { levelsBlueprint } from '/modules/levels.mjs'
import { MoveDirection } from '/modules/enums.mjs'
import { fillLevelsSelection, selectLevel } from '/modules/levelSelection.mjs'
import { fillLevelsSelection, selectLevel, LevelManager } from '/modules/levelSelection.mjs'
import { Timer } from '/modules/timer.mjs'
import { TutorialControler } from '/modules/tutorialControler.mjs'
import { Scoreboard } from '/modules/scoreboard.mjs'
@ -26,6 +26,10 @@ let gameState = {
alert("Les vaches mangent le foin");
}),
playable: false,
levelManager: new LevelManager( () => {
alert("Toutes les bottes sont rangées");
gameState.timer.stop();
} ),
levelId: 0,
};
@ -55,14 +59,21 @@ window.addEventListener("keydown", (event) => {
}
gameState.playground.draw(ctx, canvas.width, canvas.height);
if (gameState.playground.isSolved()) {
gameState.levelId++;
selectLevel(ctx, gameState, gameState.levelId);
gameState.levelManager.next(ctx, gameState);
}
} else {
tutorial.next();
if (tutorial.isFinished()) {
gameState.playable = true;
gameState.timer.start();
switch (event.key) {
case "ArrowRight":
case " ":
case "Enter":
tutorial.next();
if (tutorial.isFinished()) {
gameState.playable = true;
gameState.timer.start();
}
break;
default:
break;
}
}
}

Voir le fichier

@ -6,29 +6,107 @@
body {
background-color: var(--main-background-color);
color: --main-invert-color;
color: --main-text-color;
display: flex;
flex-direction: column;
margin: 0;
min-height: 100vh;
}
main {
display: flex;
flex-direction: column;
align-items: center;
float: left;
}
.container {
padding: 2rem 0 0 0;
display: flex;
min-height: 40vh;
}
aside {
margin: 0 auto;
float: left;
width: 20rem;
justify-content: space-between;
flex-direction: column;
}
nav {
display: flex;
background-color: yellowgreen;
padding: 0 20%;
}
nav ol {
display: flex;
flex-direction: row;
align-items: center;
list-style-type: none;
}
nav ol li {
margin: auto 1rem;
}
nav ol li button {
background-color: transparent;
padding: 0.5rem;
font-size: large;
}
footer {
display: flex;
align-items: center;
flex-direction: column;
position:fixed;
margin-top: auto;
width: 100%;
bottom: 0;
background-color: yellowgreen;
}
footer p:last-child {
font-weight: bolder;
}
table {
border-collapse: collapse;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
width:100%;
}
thead {
width:100%;
background:#000;
padding:(12px * 1.5) 0;
color:wheat;
}
tr {
text-align: center;
width:100%;
padding:(12px * 1.5) 0;
}
tr:nth-of-type(even) {
background:lightgray;
}
.text-bubble {
/* transform: rotate(90deg); */
position: relative;
margin: auto;
margin-left: 658px;
margin-top: -385px;
margin-left: 185px;
margin-top: -395px;
z-index: 2;
}
.dialog {
height: 200px;
width: 400px;
height: 150px;
width: 350px;
background-color: var(--main-background-color);
position: relative;
border-radius: 10%;
@ -37,7 +115,7 @@ main {
border: 1px solid black;
}
.left-point {
.right-point {
width: 0;
height: 0;
border-left: 1rem solid transparent;
@ -45,19 +123,18 @@ main {
border-top: 5rem solid black;
position: absolute;
margin-top: 30%;
margin-left: -10%;
transform: rotate(60deg) ;
margin-left: 100%;
transform: rotate(-60deg) ;
z-index: -1;
}
.shifted {
transform:rotate(60deg) translate(0px,-2px);
transform:rotate(-60deg) translate(0px,-2px);
border-top: 5rem solid white;
z-index: 4;
}
.speech {
z-index: 3;
margin: auto;

Voir le fichier

@ -17,3 +17,10 @@
* Prompt for username after ending
* Table with filled usernames
## Insectes
* Error when last level is successfully finished
* Size of the canvas: tiles not squared with some levels
* Timer does not stop on win
* Le tracteur devient John Cena