Skip to content

Commit 9e9cb91

Browse files
committed
added part library
1 parent d7b0c74 commit 9e9cb91

26 files changed

+1623
-175
lines changed

Parts/Children/AnimatedSprite.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,18 @@ export class AnimatedSprite extends Renderer {
3333
this.webEngine = webEngine; // Set the web engine flag
3434
this.type = "AnimatedSprite";
3535
}
36-
36+
destroy() {
37+
super.destroy();
38+
// Clean up the loaded spritesheet image
39+
if (this.loadedSheet) {
40+
this.loadedSheet.src = ""; // Release the image source
41+
this.loadedSheet = undefined;
42+
}
43+
// Clear the frames
44+
this.frames = {};
45+
this.spritesheetData = undefined; // Clear the spritesheet data
46+
this.spritesheet = ""; // Clear the spritesheet path
47+
}
3748
async onMount(parent: Part) {
3849
super.onMount(parent);
3950
parent.setSuperficialDimensions(this.width, this.height); // Set dimensions for the parent part

Parts/Game.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Sound } from "../engine/bundle";
12
import { getDebugInfo } from "../helpers";
23
import { Part } from "./Part";
34
import { Scene } from "./Scene";
@@ -168,10 +169,13 @@ export class Game extends Part {
168169

169170
pause() {
170171
this._isPaused = true;
172+
SoundManager.pauseGame();
173+
171174
}
172175

173176
resume() {
174177
this._isPaused = false;
178+
SoundManager.resumeGame();
175179
}
176180

177181
stop() {
@@ -182,6 +186,11 @@ export class Game extends Part {
182186
this._animationFrameId = undefined;
183187
}
184188
SoundManager.stopGame();
189+
190+
// Dump everything from memory
191+
this.childrenArray.forEach(scene => {
192+
scene.destroy();
193+
});
185194
}
186195

187196
get isRunning(): boolean {

Parts/Input.ts

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ export class Input extends Part {
1515
currentMousePos: { x: number, y: number } = { x: 0, y: 0 };
1616
lastClickPos: { x: number, y: number } | null = null;
1717
initialized: boolean; // Have the event listeners been initialized?
18+
private mousemoveDef?: (event: MouseEvent) => void; // Store the mousemove event handler (definite)
19+
private clickDef?: (event: MouseEvent) => void; // Store the click event handler (definite)
20+
private mousedownDef?: (event: MouseEvent) => void;
21+
private mouseupDef?: (event: MouseEvent) => void;
22+
private keydownDef?: (event: KeyboardEvent) => void;
23+
private keyupDef?: (event: KeyboardEvent) => void;
24+
1825
constructor({
1926
key,
2027
keyup,
@@ -36,7 +43,7 @@ export class Input extends Part {
3643
this.type = "Input";
3744
}
3845
initialize(canvas: HTMLCanvasElement) {
39-
canvas.addEventListener("mousemove", (event) => {
46+
this.mousemoveDef = (event: MouseEvent) => {
4047
const game = this.top as Game;
4148
if (!game || !game.currentScene || game.currentScene !== this.parent || !game.currentScene?.activeCamera) {
4249
return;
@@ -66,9 +73,8 @@ export class Input extends Part {
6673

6774

6875
this.currentMousePos = { x: finalX, y: finalY };
69-
});
70-
71-
canvas.addEventListener("click", (event) => {
76+
}
77+
this.clickDef = (event) => {
7278
const game = this.top as Game;
7379
if (!game || !game.currentScene || game.currentScene !== this.parent || !game.currentScene?.activeCamera) {
7480
return;
@@ -98,33 +104,51 @@ export class Input extends Part {
98104

99105

100106
this.lastClickPos = { x: finalX, y: finalY };
101-
});
102-
canvas.addEventListener("mousedown", (event) => {
107+
}
108+
this.mousedownDef = (event) => {
103109
const game = this.top as Game;
104110
if (game.hovering) {
105111
game.hovering.onmousedown(event);
106112
}
107-
});
108-
canvas.addEventListener("mouseup", (event) => {
113+
}
114+
this.mouseupDef = (event) => {
109115
const game = this.top as Game;
110116
if (game.hovering) {
111117
game.hovering.onmouseup(event);
112118
}
113-
});
114-
115-
document.addEventListener("keydown", (event) => {
119+
}
120+
this.keydownDef = (event) => {
116121
this.downkeys.add(event.key);
117-
});
118-
document.addEventListener("keyup", (event) => {
122+
}
123+
this.keyupDef = (event) => {
119124
this.downkeys.delete(event.key);
120125
if (typeof this.keyup == "function") {
121126
this.keyup(event);
122127
}
123-
});
128+
}
129+
canvas.addEventListener("mousemove", this.mousemoveDef);
130+
canvas.addEventListener("click",this.clickDef);
131+
canvas.addEventListener("mousedown", this.mousedownDef);
132+
canvas.addEventListener("mouseup", this.mouseupDef);
133+
134+
document.addEventListener("keydown", this.keydownDef);
135+
document.addEventListener("keyup", this.keyupDef);
124136
this.initialized = true; // Mark as initialized after setting up listeners
125137
}
126138

127-
139+
destroy(): void {
140+
super.destroy();
141+
const canvas = this.top?.canvas;
142+
if (canvas) {
143+
// Remove all event listeners
144+
canvas.removeEventListener("mousemove", this.mousemoveDef!);
145+
canvas.removeEventListener("click", this.clickDef!);
146+
canvas.removeEventListener("mousedown", this.mousedownDef!);
147+
canvas.removeEventListener("mouseup", this.mouseupDef!);
148+
document.removeEventListener("keydown", this.keydownDef!);
149+
document.removeEventListener("keyup", this.keyupDef!);
150+
}
151+
}
128152
act(delta: number) {
129153
super.act(delta);
130154
if (!this.initialized) {

Parts/Part.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import type { Collider } from "./Children/Collider";
66
import type { Scene } from "./Scene";
77

88
type Tie<T extends Part = Part, L extends keyof T = keyof T, R extends keyof Part = keyof Part> = {
9-
target: T;
10-
localAttribute: R;
11-
targetAttribute: L;
9+
target: T;
10+
localAttribute: R;
11+
targetAttribute: L;
1212
};
1313

1414

@@ -42,6 +42,7 @@ export class Part {
4242
this.parent = undefined;
4343
this.top = undefined;
4444
this.ready = true;
45+
this.type = this.constructor.name || "Part"; // Default type is the class name
4546
this.debugEmoji = "🧩"; // Default emoji for debugging
4647
}
4748
tie<T extends Part>(
@@ -54,7 +55,9 @@ export class Part {
5455
if (target.hasOwnProperty(targetAttribute as string)) {
5556
this.ties.add({
5657
target,
58+
// @ts-ignore - Intentionally allowing flexible typing for ties
5759
localAttribute,
60+
// @ts-ignore - Intentionally allowing flexible typing for ties
5861
targetAttribute
5962
});
6063
}
@@ -128,13 +131,15 @@ export class Part {
128131
switch (attribute) {
129132
case "parent":
130133
this.parent = undefined; // Clear parent reference
131-
this.registrations.layer.flats.colliders = this.registrations.layer.flats.colliders.filter((c: Collider) => c as any !== this as any);
134+
if (this.registrations.layer && this.registrations.layer.flats) {
135+
this.registrations.layer.flats.colliders = this.registrations.layer.flats.colliders.filter((c: Collider) => c as any !== this as any);
136+
}
132137
break;
133138
case "top":
134139
this.top = undefined; // Clear top reference
135140
break;
136141
case "layer":
137-
if (this.registrations.layer) {
142+
if (this.registrations.layer && this.registrations.layer.flats) {
138143
this.registrations.layer.flats.colliders = this.registrations.layer.flats.colliders.filter((c: Collider) => c as any !== this as any);
139144
}
140145
break;
@@ -176,7 +181,7 @@ export class Part {
176181
}
177182
}
178183
attr<T>(attribute: string, value?: T): T | undefined {
179-
if (!value ) {
184+
if (!value) {
180185
return (this as any)[attribute] as T;
181186
}
182187
(this as any)[attribute] = value;

Parts/ParticleEmitter.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ class Particle extends Part {
2222
}));
2323
this.addChild(new ColorRender({ width: size, height: size, color }));
2424
}
25+
destroy(): void {
26+
super.destroy();
27+
this.velocity = Vector.From(0); // Reset velocity
28+
this.lifetime = 0;
29+
}
2530

2631
act(delta: number) {
2732
super.act(delta);
@@ -79,6 +84,13 @@ export class ParticleEmitter extends Part {
7984
super.onMount(parent);
8085
if (this.top?.devmode) parent.addChild(new ColorRender({ width: 100, height: 100, color: "rgba(255, 255, 255, 0.5)" }));
8186
}
87+
destroy(): void {
88+
super.destroy();
89+
// Clean up particles
90+
this.particles = [];
91+
this.lastEmissionTime = 0;
92+
this.emittedCount = 0;
93+
}
8294
act(delta: number) {
8395
super.act(delta);
8496
const now = Date.now();
@@ -95,7 +107,6 @@ export class ParticleEmitter extends Part {
95107
lifetime: this.particleLifetime
96108
});
97109
this.addChild(particle);
98-
console.log(this);
99110
particle.child<Transform>("Transform")!.position = transform.position.clone(); // Start at emitter's position
100111
this.emittedCount++;
101112
this.lastEmissionTime = now;

Parts/PhysicsEngine.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,14 @@ export class PhysicsEngine extends Part {
2020
this.debugEmoji = "⚛️";
2121
this.type = "PhysicsEngine";
2222
}
23-
23+
destroy(): void {
24+
super.destroy();
25+
// Clean up the physics engine
26+
if (this.world) {
27+
World.clear(this.world, false); // Clear the world without resetting the engine
28+
this.engine = Engine.create(); // Reset the engine
29+
}
30+
}
2431
onMount(parent: Part) {
2532
super.onMount(parent);
2633
}

Parts/SoundManager.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,17 @@ class SoundManagerController {
2222
}
2323

2424
public unregisterSound(sound: Sound): void {
25+
sound.stop(); // Stop the sound before unregistering
2526
this.sounds = this.sounds.filter(s => s !== sound);
2627
}
28+
public pauseGame(): void {
29+
this.isGameRunning = false;
30+
this.sounds.forEach(sound => sound.pause());
31+
}
32+
public resumeGame(): void {
33+
this.isGameRunning = true;
34+
this.sounds.forEach(sound => sound.play({ restart: true }));
35+
}
2736

2837
public startGame(): void {
2938
this.isGameRunning = true;
@@ -33,10 +42,17 @@ class SoundManagerController {
3342
}
3443
});
3544
}
36-
45+
public unregisterAllSounds(): void {
46+
this.sounds.forEach(sound => sound.stop());
47+
this.sounds = [];
48+
}
3749
public stopGame(): void {
3850
this.isGameRunning = false;
3951
this.sounds.forEach(sound => sound.stop());
52+
// Dump sounds from memory
53+
SoundManager.unregisterAllSounds();
54+
55+
//
4056
}
4157

4258
public getIsGameRunning(): boolean {

docs/api-reference.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ This section provides a detailed reference for the core classes and components i
1616
- [Transform](./api/Transform.md)
1717
- [Camera](./api/Camera.md)
1818
- [Input](./api/Input.md)
19+
- [Sound](./api/Sound.md)
20+
- [ParallaxLayer](./api/ParallaxLayer.md)
21+
1922

2023
### Renderers
2124
- [Renderer](./api/Renderer.md) (Base class)
@@ -25,11 +28,38 @@ This section provides a detailed reference for the core classes and components i
2528
- [TextRender](./api/TextRender.md)
2629
- [Button](./api/Button.md)
2730

31+
2832
### Colliders
2933
- [Collider](./api/Collider.md) (Base class)
3034
- [BoxCollider](./api/BoxCollider.md)
3135
- [PolygonCollider](./api/PolygonCollider.md)
36+
- [AreaTrigger](./api/AreaTrigger.md)
37+
38+
39+
40+
### Game Logic
41+
42+
- [CameraShake](./api/CameraShake.md)
43+
- [CharacterMovement](./api/CharacterMovement.md)
44+
- [Follow](./api/Follow.md)
45+
- [Health](./api/Health.md)
46+
- [HealthBar](./api/HealthBar.md)
47+
- [ParticleEmitter](./api/ParticleEmitter.md)
48+
- [Projectile](./api/Projectile.md)
49+
- [Spawner](./api/Spawner.md)
50+
- [Timer](./api/Timer.md)
51+
- [WaypointFollower](./api/WaypointFollower.md)
52+
-
53+
54+
### Phyiscs
55+
- [PhysicsBody](./api/PhysicsBody.md)
56+
- [PhysicsEngine](./api/PhysicsEngine.md)
57+
58+
### Misc.
59+
- [Rotator](./api/Rotator.md)
60+
- [Scaler](./api/Scaler.md)
3261

3362
## Math
3463

35-
- [Vector](./api/Vector.md)
64+
- [Vector](./api/Vector.md)
65+

0 commit comments

Comments
 (0)