This commit is contained in:
Axel O 2022-12-12 17:20:26 +01:00
commit 109971f1d6
8 changed files with 246 additions and 48 deletions

View file

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

View file

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

View file

@ -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,
];

View file

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

View file

@ -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!",

View file

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

View file

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

View file

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