Compare commits

...

2 commits

Author SHA1 Message Date
lagaffe
4ffe8a162b add game manager to handle game life cycle, add onEnd callback to Game class 2026-04-28 17:32:46 +02:00
lagaffe
5aae54fe65 add text instructions for each game 2026-04-28 16:27:05 +02:00
12 changed files with 132 additions and 13 deletions

View file

@ -1,3 +1,8 @@
### divers
- messages d'explication des jeux
- fade out au bout d'un certain temps
- fade out dès que le score du jeu bouge
### mini game ideas
#### fridge

View file

@ -22,3 +22,7 @@ export function getIntersection(a, b, out = new Rectangle()) {
return out;
}
export function getRandomInt(max) {
return Math.floor(Math.random() * max);
}

View file

@ -1,4 +1,5 @@
export { backgroundLayout } from "./layouts";
export { makeDragable, makeUnDragable } from "./dragAndDrop";
export { getIntersection } from "./helpers";
export { getRandomInt } from "./helpers";
export { KeyBoardListener } from "./keyBoardEvents";

65
src/gameManager.js Normal file
View file

@ -0,0 +1,65 @@
import { getRandomInt } from "./common";
import { Fridge, Opinator, SmartMonday, CleanupHS } from "./games";
/**
* manages the game lifecyle, starting a game, handeling game end and starting a new one
* lvl up etc.
*/
export class GameManager {
constructor(app, gameContainter) {
this._app = app;
this._gameContainer = gameContainter;
this._difficulty = 1;
const opinator = new Opinator(app.ticker);
const fridge = new Fridge(app.ticker);
const smartMonday = new SmartMonday(app.ticker);
const cleanupHS = new CleanupHS(
app.stage.width,
app.stage.height,
app.ticker,
);
this._games = [opinator, fridge, smartMonday, cleanupHS];
this._playedGamesIds = [];
this._unPlayedGamesIds = [];
for (var i = 0; i < this._games.length; i++) {
this._unPlayedGamesIds.push(i);
}
this._currentGame = undefined;
}
start() {
this.nextGame();
}
nextGame() {
const unplayedLength = this._unPlayedGamesIds.length;
if (unplayedLength == 0) {
console.log("level up");
this._difficulty += 1;
this._unPlayedGamesIds = this._playedGamesIds;
this._playedGamesIds = [];
}
const nextIndex = getRandomInt(unplayedLength);
const nextId = this._unPlayedGamesIds[nextIndex];
console.log(nextIndex, this._playedGamesIds, this._unPlayedGamesIds);
this._playedGamesIds.push(this._unPlayedGamesIds[nextIndex]);
this._unPlayedGamesIds.splice(nextIndex, 1);
this._currentGame = this._games[nextId];
this._currentGame.onEnd = (status) => {
this._onGameEnd(status);
};
this._gameContainer.addChild(this._currentGame.gameContainer);
this._currentGame.start();
}
_onGameEnd(status) {
console.log("game end", status);
this._gameContainer.removeChild(this._currentGame.gameContainer);
console.log("next !");
this.nextGame();
}
}

View file

@ -35,6 +35,9 @@ export class CleanupHS extends TimedGame {
this.trashLandingZone.addChild(trashcan);
this.shelfLandingZone.addChild(shelf);
this._gameDesc.text = "Range le HS !!";
this._instruction.text = "drag & drop les objets dans le bon contenant";
this.trashLandingZone.layout = { width: "20%", height: "100%" };
this.shelfLandingZone.layout = {
width: "20%",

View file

@ -31,6 +31,9 @@ export class Fridge extends TimedGame {
this.timeout = this._bottleCount * 1500; // 1.5s per bottle
this._gameDesc.text = "Remplis le frigo !!";
this._instruction.text = "drag & drop les club mate dans le frigo";
const fridgeContainer = new Container();
fridgeContainer.layout = { width: "50%" };
const fridge = Sprite.from("frigo");

View file

@ -1,17 +1,46 @@
import { Container, RenderLayer } from "pixi.js";
import { Container, RenderLayer, Text } from "pixi.js";
export class Game {
constructor() {
this._difficulty = 1;
this.won = false;
this.onEnd = () => {};
this.gameContainer = new Container(); // main container, to add the game to a node, add this container as a child
this.gameContainer.layout = true;
/*
this._uiLayer = new Container();
this._gameObjectsLayer = new Container();*/
this._uiLayer = new RenderLayer();
this._gameObjectsLayer = new RenderLayer();
this._gameObjectsLayer.sortableChildren = true;
this._gameDesc = new Text({
text: "",
style: {
fontFamily: "Arial",
fontSize: 30,
fill: 0x000000,
align: "center",
},
});
this._instruction = new Text({
text: "",
style: {
fontFamily: "Arial",
fontSize: 30,
fill: 0x000000,
align: "center",
},
});
this._gameDesc.layout = { position: "absolute", left: "40%" };
this._instruction.layout = {
position: "absolute",
left: "40%",
top: "40%",
};
this._addUiChild(this._gameDesc);
this._addUiChild(this._instruction);
this.gameContainer.addChild(this._gameObjectsLayer);
this.gameContainer.addChild(this._uiLayer);
}
@ -28,9 +57,9 @@ export class Game {
/* status indicates if its a win or a loss */
end(status) {
this.win = status;
this.won = status;
console.log(status ? "game won" : "game lost");
// we probably want to call a callback here
this.onEnd(status);
}
_addGameObjectChild(node) {

View file

@ -12,6 +12,8 @@ export class Opinator extends TimedGame {
this._lastMousePos = undefined; // use to compute the travelled distance
this.timeout = this._baseGoalScore * 1000; // 1s per sprite len
this._gameDesc.text = "Répare opinator !!";
this._instruction.text = "clique et agite la souris";
this._backgroundSprite = Sprite.from("opinator");

View file

@ -6,11 +6,15 @@ export class SmartMonday extends TimedGame {
constructor(ticker) {
super(10000, ticker);
this._gameDesc.text = "Organise le smart monday !!";
this._instruction.text = "spam le clavier";
this._goal = 100 * this._difficulty; // number of characters
this.timeout = 1000 * (this._goal / 10); // 10 chars per second
this._currentString = "";
this._keyEventHandle = undefined;
this.gameContainer.layout = { width: "100%", height: "100%" };
}
reset() {

View file

@ -61,6 +61,6 @@ export class TimedGame extends Game {
_onTimeout() {
console.log("time end");
this.end(this._win);
this.end(this.won);
}
}

View file

@ -2,6 +2,7 @@ import "@pixi/layout";
import { Application, Assets, Container, Sprite } from "pixi.js";
import { Fridge, Opinator, SmartMonday, CleanupHS } from "./games";
import { backgroundLayout, KeyBoardListener } from "./common";
import { GameManager } from "./gameManager";
const app = new Application();
let root = new Container();
@ -96,14 +97,19 @@ function switchToGame(gameContainer, newGame) {
maxHeight: "100%",
margin: 0,
};
root.addChild(gameContainter);
const manager = new GameManager(app, gameContainter);
manager.start();
/*
const opinator = new Opinator(app.ticker);
const fridge = new Fridge(app.ticker);
const smartMonday = new SmartMonday(app.ticker);
const cleanupHS = new CleanupHS(root.width, root.height, app.ticker);
let currentGame = opinator;
let currentGame = cleanupHS;
gameContainter.addChild(currentGame.gameContainer);
root.addChild(gameContainter);
currentGame.start();
*/
})();

View file

@ -2,6 +2,3 @@
- diplay info
- game result
- game
- game name
- play instruction