Skip to content

Commit ac03383

Browse files
committed
Add idle mode.
1 parent 1108702 commit ac03383

File tree

2 files changed

+124
-3
lines changed

2 files changed

+124
-3
lines changed

src/Game.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import Background from "./nodes/Background";
77
import { initSounds } from "./audio";
88
import { inputs } from "./inputs";
99
import ministryLogoPath from "./assets/img/ministry-logo.png";
10+
import IdleMode from "./nodes/IdleMode";
11+
import { randomInt } from "mathjs";
12+
import { campaign } from "./levels";
13+
14+
const IDLE_TIMEOUT = 60 * 1000;
1015

1116
export default class Game {
1217
async start() {
@@ -38,15 +43,46 @@ export default class Game {
3843
const menu = new Menu(background, ministryLogoTexture);
3944
app.stage.addChild(background.view);
4045
app.ticker.add(background.tick);
41-
menu.show(app.stage);
46+
47+
let timeout: number;
48+
function setIdleTimeout() {
49+
timeout = setTimeout(() => {
50+
menu.hide();
51+
const idleMode = new IdleMode(
52+
background,
53+
randomInt(0, campaign.length)
54+
);
55+
idleMode.onFinish = () => {
56+
app.ticker.remove(idleMode.tick);
57+
app.stage.removeChild(idleMode.view);
58+
showMenu();
59+
};
60+
app.stage.addChild(idleMode.view);
61+
idleMode.start();
62+
app.ticker.add(idleMode.tick);
63+
}, IDLE_TIMEOUT);
64+
}
65+
const resetIdleTimeout = () => {
66+
clearTimeout(timeout);
67+
setIdleTimeout();
68+
};
69+
const showMenu = () => {
70+
menu.show(app.stage);
71+
setIdleTimeout();
72+
document.addEventListener("keydown", resetIdleTimeout);
73+
};
74+
75+
showMenu();
4276
menu.onStart = (numPlayers, level) => {
77+
document.removeEventListener("keydown", resetIdleTimeout);
78+
clearTimeout(timeout);
4379
menu.hide();
4480
if (numPlayers === 1) {
4581
const singlePlayer = new SinglePlayer(background, level);
4682
singlePlayer.onFinish = () => {
4783
app.ticker.remove(singlePlayer.tick);
4884
app.stage.removeChild(singlePlayer.view);
49-
menu.show(app.stage);
85+
showMenu();
5086
};
5187
app.stage.addChild(singlePlayer.view);
5288
singlePlayer.start();
@@ -56,7 +92,7 @@ export default class Game {
5692
multiplayer.onFinish = () => {
5793
app.ticker.remove(multiplayer.tick);
5894
app.stage.removeChild(multiplayer.view);
59-
menu.show(app.stage);
95+
showMenu();
6096
};
6197
app.stage.addChild(multiplayer.view);
6298
multiplayer.start();

src/nodes/IdleMode.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { Point, type Ticker } from "pixi.js";
2+
import { WIDTH } from "../constants";
3+
import GameNode from "./GameNode";
4+
import Player from "./Player";
5+
import { campaign } from "../levels";
6+
import Background from "./Background";
7+
import { inputs } from "../inputs";
8+
import Countdown from "./Countdown";
9+
import { type IMediaInstance } from "@pixi/sound";
10+
import { playSound } from "../audio";
11+
import { slideIn } from "../animations";
12+
import { UP } from "../points";
13+
import { choice } from "../random";
14+
15+
type Mode = "game" | "score";
16+
17+
export default class IdleMode extends GameNode {
18+
player: Player;
19+
onFinish?: () => void;
20+
background: Background;
21+
mode: Mode = "game";
22+
music?: IMediaInstance;
23+
24+
constructor(background: Background, startLevel: number) {
25+
super();
26+
this.background = background;
27+
this.player = new Player({
28+
inputMap: inputs.player1,
29+
levels: campaign,
30+
startLevel,
31+
});
32+
this.player.onLevelUp = (level) => {
33+
this.background.setGenerator(level.randomQubit);
34+
};
35+
this.player.onTopOut = () => {
36+
this.music?.stop();
37+
};
38+
this.player.onGameOver = () => {
39+
this.view.removeChild(this.player.view);
40+
this.player.destroy();
41+
this.endIdle();
42+
};
43+
}
44+
45+
async start() {
46+
// this.view.addChild(
47+
// new HTMLText({
48+
// text: "Press any button",
49+
// })
50+
// );
51+
this.view.addChild(this.player.view);
52+
document.addEventListener("keydown", this.handleKeyDown);
53+
slideIn(
54+
this.player.view,
55+
new Point(WIDTH / 2 - this.player.view.width / 2, 0),
56+
UP
57+
);
58+
59+
const countdown = new Countdown();
60+
this.view.addChild(countdown.view);
61+
await countdown.start();
62+
this.player.start();
63+
this.view.removeChild(countdown.view);
64+
this.music = await playSound("bgMusic", { loop: true });
65+
}
66+
67+
tick = (time: Ticker) => {
68+
if (this.mode === "game") {
69+
this.player.tick(time);
70+
// Very simple, just press a random button
71+
if (Math.random() < 0.02)
72+
this.player.onPress(choice(Object.values(inputs.player1)));
73+
}
74+
};
75+
76+
endIdle() {
77+
this.music?.stop();
78+
document.removeEventListener("keydown", this.handleKeyDown);
79+
this.onFinish?.();
80+
}
81+
82+
handleKeyDown = () => {
83+
this.endIdle();
84+
};
85+
}

0 commit comments

Comments
 (0)