Skip to content
This repository was archived by the owner on Nov 13, 2023. It is now read-only.

Commit 7772a0c

Browse files
authored
Merge branch bugfix/infinite-asset-loading-loop into main (#102)
* Fix infinite asset loading - Implement events for asset loading in AssetLoader - Adapt main game class to new AssetLoader events.
1 parent 1675794 commit 7772a0c

File tree

5 files changed

+137
-40
lines changed

5 files changed

+137
-40
lines changed

src/ts/engine/assets/assetloader.ts

Lines changed: 90 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,122 @@
1+
import EngineEvent from "../event/engineevent.js";
2+
import EngineEventHandler from "../event/engineventhandler.js";
13
import AssetVerifier from "./assetverifier.js";
24

35
class AssetLoader {
46
private _images: Map<string, HTMLImageElement>;
57
private _audio: Map<string, HTMLAudioElement>;
68

7-
constructor() {
9+
private _imagesLoadedEvent: EngineEventHandler<boolean, EngineEvent<boolean>>;
10+
private _audiosLoadedEvent: EngineEventHandler<boolean, EngineEvent<boolean>>;
11+
private _assetsLoadedEvent: EngineEventHandler<boolean, EngineEvent<boolean>>;
12+
13+
private _imageLoadTrackerTask: number | undefined;
14+
private _audioLoadTrackerTask: number | undefined;
15+
private _assetLoadTrackerTask: number | undefined;
16+
17+
public get imagesLoadedEvent(): EngineEventHandler<
18+
boolean,
19+
EngineEvent<boolean>
20+
> {
21+
return this._imagesLoadedEvent;
22+
}
23+
24+
public get audiosLoadedEvent(): EngineEventHandler<
25+
boolean,
26+
EngineEvent<boolean>
27+
> {
28+
return this._audiosLoadedEvent;
29+
}
30+
31+
public get assetsLoadedEvent(): EngineEventHandler<
32+
boolean,
33+
EngineEvent<boolean>
34+
> {
35+
return this._assetsLoadedEvent;
36+
}
37+
38+
public constructor() {
839
this._images = new Map<string, HTMLImageElement>();
940
this._audio = new Map<string, HTMLAudioElement>();
10-
}
1141

12-
hasImage(key: string): boolean {
42+
this._imagesLoadedEvent = new EngineEventHandler<
43+
boolean,
44+
EngineEvent<boolean>
45+
>();
46+
this._audiosLoadedEvent = new EngineEventHandler<
47+
boolean,
48+
EngineEvent<boolean>
49+
>();
50+
this._assetsLoadedEvent = new EngineEventHandler<
51+
boolean,
52+
EngineEvent<boolean>
53+
>();
54+
}
55+
56+
public hasImage(key: string): boolean {
1357
return this._images.has(key);
1458
}
1559

16-
getImage(key: string): HTMLImageElement {
60+
public getImage(key: string): HTMLImageElement {
1761
if (!this.hasImage(key)) {
1862
throw new Error(`Image with key ${key} does not exist!`);
1963
}
2064

2165
return this._images.get(key) as HTMLImageElement;
2266
}
2367

24-
getImagesCount(): number {
68+
public getImagesCount(): number {
2569
return this._images.size;
2670
}
2771

28-
getImagesReadyCount(): number {
72+
public getImagesReadyCount(): number {
2973
return Array.from(this._images.values())
3074
.map((image) => AssetVerifier.verifyImage(image))
3175
.filter((status) => status === true).length;
3276
}
3377

34-
areImagesReady(): boolean {
78+
public areImagesReady(): boolean {
3579
return this.getImagesCount() === this.getImagesReadyCount();
3680
}
3781

38-
hasAudio(key: string): boolean {
82+
public hasAudio(key: string): boolean {
3983
return this._audio.has(key);
4084
}
4185

42-
getAudio(key: string): HTMLAudioElement {
86+
public getAudio(key: string): HTMLAudioElement {
4387
if (!this.hasAudio(key)) {
4488
throw new Error(`Audio with key ${key} does not exist!`);
4589
}
4690
return this._audio.get(key) as HTMLAudioElement;
4791
}
4892

49-
getAudiosCount(): number {
93+
public getAudiosCount(): number {
5094
return this._audio.size;
5195
}
5296

53-
getAudiosReadyCount(): number {
97+
public getAudiosReadyCount(): number {
5498
return Array.from(this._audio.values())
5599
.map((audio) => AssetVerifier.verifyAudio(audio))
56100
.filter((status) => status === true).length;
57101
}
58102

59-
areAudiosReady(): boolean {
103+
public areAudiosReady(): boolean {
60104
return this.getAudiosCount() === this.getAudiosReadyCount();
61105
}
62106

63-
getAssetsCount(): number {
107+
public getAssetsCount(): number {
64108
return this.getImagesCount() + this.getAudiosCount();
65109
}
66110

67-
getAssetsReadyCount(): number {
111+
public getAssetsReadyCount(): number {
68112
return this.getImagesReadyCount() + this.getAudiosReadyCount();
69113
}
70114

71-
areAssetsReady(): boolean {
115+
public areAssetsReady(): boolean {
72116
return this.getAssetsCount() === this.getAssetsReadyCount();
73117
}
74118

75-
registerImages(className: string) {
119+
public registerImages(className: string) {
76120
let images = document.getElementsByClassName(className);
77121
if (images.length == 0) {
78122
console.warn(`No images found for class ${className}`);
@@ -92,7 +136,7 @@ class AssetLoader {
92136
}
93137
}
94138

95-
registerAudios(className: string) {
139+
public registerAudios(className: string) {
96140
let audio = document.getElementsByClassName(className);
97141
if (audio.length == 0) {
98142
console.warn(`No audios found for class ${className}`);
@@ -111,6 +155,35 @@ class AssetLoader {
111155
this._audio.set(audioElement.id, audioElement);
112156
}
113157
}
158+
159+
public startTracking() {
160+
this._imageLoadTrackerTask = setInterval(() => {
161+
let imagesReady = this.areImagesReady();
162+
this._imagesLoadedEvent.dispatch(new EngineEvent<boolean>(imagesReady));
163+
164+
if (imagesReady) {
165+
clearInterval(this._imageLoadTrackerTask);
166+
}
167+
}, 500);
168+
169+
this._audioLoadTrackerTask = setInterval(() => {
170+
let audiosReady = this.areAudiosReady();
171+
this._audiosLoadedEvent.dispatch(new EngineEvent<boolean>(audiosReady));
172+
173+
if (audiosReady) {
174+
clearInterval(this._audioLoadTrackerTask);
175+
}
176+
}, 500);
177+
178+
this._assetLoadTrackerTask = setInterval(() => {
179+
let assetsReady = this.areAssetsReady();
180+
this._assetsLoadedEvent.dispatch(new EngineEvent<boolean>(assetsReady));
181+
182+
if (assetsReady) {
183+
clearInterval(this._assetLoadTrackerTask);
184+
}
185+
}, 500);
186+
}
114187
}
115188

116189
export default AssetLoader;

src/ts/engine/game.ts

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import CookieManager from "./cookies/cookiemanager.js";
55
import Services from "./dependencyinjection/services.js";
66
import EngineSetup from "./enginesetup.js";
77
import EntityManager from "./entitiy/entitymanager.js";
8+
import EngineEvent from "./event/engineevent.js";
89
import InputHandler from "./input/inputhandler.js";
910
import LevelManager from "./level/levelmanager.js";
1011
import Compositor from "./renderer/compositor.js";
@@ -93,25 +94,31 @@ class Game {
9394
this._levelManager
9495
);
9596

96-
while (!this._assetLoader.areAssetsReady()) {
97-
console.log("Loading assets...");
98-
}
99-
100-
engineSetup.registerTextures(
101-
this._assetLoader,
102-
this._assetManager,
103-
this._entityManager,
104-
this._levelManager
105-
);
106-
107-
engineSetup.registerLevels(
108-
this._assetLoader,
109-
this._assetManager,
110-
this._entityManager,
111-
this._levelManager
97+
this._assetLoader.assetsLoadedEvent.subscribe(
98+
(engineEvent: EngineEvent<boolean>) => {
99+
if (!engineEvent.eventData) {
100+
console.log("Loading assets...");
101+
} else {
102+
engineSetup.registerTextures(
103+
this._assetLoader,
104+
this._assetManager,
105+
this._entityManager,
106+
this._levelManager
107+
);
108+
109+
engineSetup.registerLevels(
110+
this._assetLoader,
111+
this._assetManager,
112+
this._entityManager,
113+
this._levelManager
114+
);
115+
116+
engineSetup.registerScenes(this._sceneManager);
117+
}
118+
}
112119
);
113120

114-
engineSetup.registerScenes(this._sceneManager);
121+
this._assetLoader.startTracking();
115122
}
116123

117124
public startUpdateLoop(): void {

src/ts/game/main.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import SpriteSheet from "../engine/assets/texture/spritesheet.js";
66
import Cookie from "../engine/cookies/cookie.js";
77
import CookieManager from "../engine/cookies/cookiemanager.js";
88
import Services from "../engine/dependencyinjection/services.js";
9+
import EngineEvent from "../engine/event/engineevent.js";
910
import Game from "../engine/game.js";
1011
import InputHandler from "../engine/input/inputhandler.js";
1112
import LevelManager from "../engine/level/levelmanager.js";
@@ -28,17 +29,34 @@ function getGameCanvas(): HTMLCanvasElement {
2829
return canvas;
2930
}
3031

31-
function start(): void {
32+
function init(): void {
3233
let htmlCanvasElement: HTMLCanvasElement = getGameCanvas();
3334
let game: Game = new Game(htmlCanvasElement, new GameSetup());
35+
3436
window.addEventListener("beforeunload", game.stopGame.bind(game));
3537

3638
let inputHandler: InputHandler =
3739
Services.resolve<InputHandler>("InputHandler");
3840
inputHandler.addWhiteListedKeys(["F5", "F11", "F12", "Alt"]);
3941

40-
game.startGame();
42+
let assetLoader = Services.resolve<AssetLoader>("AssetLoader");
43+
44+
if (!assetLoader.areAssetsReady()) {
45+
assetLoader.assetsLoadedEvent.subscribe(
46+
(engineEvent: EngineEvent<boolean>) => {
47+
if (engineEvent.eventData) {
48+
start(game);
49+
}
50+
}
51+
);
52+
} else {
53+
start(game);
54+
}
55+
}
56+
57+
function start(game: Game): void {
4158
Services.resolve<SceneManager>("SceneManager").switch("mainmenu");
59+
game.startGame();
4260
}
4361

44-
window.addEventListener("DOMContentLoaded", start);
62+
window.addEventListener("DOMContentLoaded", init);

src/ts/game/scenes/leveloverview.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class LevelOverview extends Base {
2525

2626
private _backToMainMenu: Button;
2727
private _reset: Button;
28-
_audioPlayer: AudioPlayer;
28+
private _audioPlayer: AudioPlayer;
2929

3030
public constructor() {
3131
super(

src/ts/game/scenes/mainmenu.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,8 @@ class MainMenu extends Base {
9898

9999
public open(): void {
100100
super.open();
101-
console.log(this._audioPlayer.currentMusic);
102101
if (
103-
this._audioPlayer.currentMusic === null ||
102+
!this._audioPlayer.currentMusic ||
104103
this._audioPlayer.currentMusic.id !== "track4"
105104
) {
106105
this._audioPlayer.play(

0 commit comments

Comments
 (0)