Skip to content

Commit d7b0c74

Browse files
committed
whoopee
1 parent b9352ef commit d7b0c74

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+2672
-4371
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,6 @@ dist
173173

174174
# Finder (MacOS) folder config
175175
.DS_Store
176+
177+
# Bun package manager files
178+
bun.lock

Math/Vector.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ export class Vector {
55
this.x = x;
66
this.y = y;
77
}
8-
8+
distance(other: Vector): number {
9+
return Math.sqrt((this.x - other.x) ** 2 + (this.y - other.y) ** 2);
10+
}
911
add(other: number | Vector): Vector {
1012
if (other instanceof Vector) {
1113
return new Vector(this.x + other.x, this.y + other.y);

Parts/AreaTrigger.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ export class AreaTrigger extends Part {
66
onExit?: (other: Collider) => void;
77
activeCollisions: Set<Collider> = new Set();
88

9-
constructor({ name, onEnter, onExit }: { name?: string, onEnter?: (other: Collider) => void, onExit?: (other: Collider) => void }) {
10-
super({ name: name || 'AreaTrigger' });
9+
constructor({ onEnter, onExit }: { onEnter?: (other: Collider) => void, onExit?: (other: Collider) => void }) {
10+
super({ name: 'AreaTrigger' });
1111
this.onEnter = onEnter;
1212
this.onExit = onExit;
1313
this.debugEmoji = "🧲";
14+
this.type = "AreaTrigger";
1415
}
1516

1617
act(delta: number) {

Parts/Camera.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import { Scene } from "./Scene";
77
export class Camera extends Part {
88
zoom: Vector;
99

10-
constructor({ name }: { name: string, zoom?: Vector }) {
11-
super();
12-
this.name = name;
10+
constructor({ name, zoom }: { name: string, zoom?: Vector }) {
11+
super({ name });
1312
this.zoom = Vector.From(1);
1413
this.debugEmoji = "📷"; // Camera specific emoji for debugging
14+
this.type = "Camera";
1515
}
1616

1717
onMount(parent: Part) {
@@ -38,15 +38,20 @@ export class Camera extends Part {
3838

3939
getViewMatrix(): { offset: Vector; scale: Vector } {
4040
// Could be used in rendering context
41+
const transform = this.child<Transform>("Transform")
42+
if (!transform) {
43+
console.warn(`Camera <${this.name}> (${this.id}) does not have a Transform component. View matrix will not be calculated.`);
44+
return { offset: Vector.From(0), scale: this.zoom };
45+
}
4146
return {
42-
offset: (this.children["Transform"] as Transform).worldPosition.multiply(-1), // View shift is inverse of camera
47+
offset: (transform).worldPosition.multiply(-1), // View shift is inverse of camera
4348
scale: this.zoom
4449
};
4550
}
4651

4752
act(delta: number) {
4853
super.act(delta);
49-
const transform = this.children["Transform"] as Transform;
54+
const transform = this.child<Transform>("Transform");
5055
if (transform) {
5156
this.zoom = transform.scale;
5257
} else {

Parts/CameraShake.ts

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,68 @@
11
import { Part } from "./Part";
2-
import { Camera } from "./Camera";
32
import { Transform } from "./Children/Transform";
43
import { Vector } from "../Math/Vector";
4+
import type { Follow } from "./Follow";
55

66
export class CameraShake extends Part {
77
intensity: number;
88
duration: number;
9+
initialized: boolean = false;
910
private shakeTimer: number = 0;
1011
private originalCameraPosition: Vector | null = null;
1112

12-
constructor({ name, intensity = 5, duration = 60 }: { name?: string, intensity?: number, duration?: number }) {
13-
super({ name: name || 'CameraShake' });
13+
constructor({ intensity = 5, duration = 60 }: { intensity?: number, duration?: number }) {
14+
super({ name:'CameraShake' });
1415
this.intensity = intensity;
1516
this.duration = duration;
1617
this.debugEmoji = " tremors";
18+
this.type = "CameraShake";
1719
}
1820

19-
onMount(parent: Part) {
20-
super.onMount(parent);
21+
initialize() {
22+
this.initialized = true;
2123
// Find the camera in the scene and store its original position
2224
const camera = this.top?.currentScene?.activeCamera;
2325
if (camera) {
24-
const cameraTransform = camera.children["Transform"] as Transform | undefined;
26+
const cameraTransform = camera.child<Transform>("Transform");
2527
if (cameraTransform) {
2628
this.originalCameraPosition = cameraTransform.position.clone();
2729
}
2830
}
2931
}
30-
3132
shake() {
3233
this.shakeTimer = this.duration;
3334
}
3435

3536
act(delta: number) {
3637
super.act(delta);
38+
if (!this.initialized) {
39+
this.initialize();
40+
}
41+
42+
const camera = this.top?.currentScene?.activeCamera;
43+
const follow = camera?.child<Follow>("Follow");
44+
const transform = camera?.child<Transform>("Transform");
45+
3746
if (this.shakeTimer > 0) {
38-
const camera = this.top?.currentScene?.activeCamera;
39-
if (camera) {
40-
const cameraTransform = camera.children["Transform"] as Transform | undefined;
41-
if (cameraTransform) {
42-
const offsetX = (Math.random() - 0.5) * this.intensity;
43-
const offsetY = (Math.random() - 0.5) * this.intensity;
44-
cameraTransform.moveTo(this.originalCameraPosition!.add(new Vector(offsetX, offsetY)));
45-
}
47+
const offsetX = (Math.random() - 0.5) * this.intensity;
48+
const offsetY = (Math.random() - 0.5) * this.intensity;
49+
50+
if (follow) {
51+
follow.externalOffset.set(offsetX, offsetY);
52+
} else if (transform && this.originalCameraPosition) {
53+
transform.moveTo(this.originalCameraPosition.add(new Vector(offsetX, offsetY)));
4654
}
55+
4756
this.shakeTimer--;
48-
} else if (this.originalCameraPosition) {
49-
// Reset camera position after shake
50-
const camera = this.top?.currentScene?.activeCamera;
51-
if (camera) {
52-
const cameraTransform = camera.children["Transform"] as Transform | undefined;
53-
if (cameraTransform) {
54-
cameraTransform.moveTo(this.originalCameraPosition);
55-
}
57+
} else {
58+
if (follow) {
59+
follow.externalOffset.set(0, 0);
60+
} else if (transform && this.originalCameraPosition) {
61+
transform.moveTo(this.originalCameraPosition);
5662
}
5763
}
64+
5865
this.hoverbug = `Shaking: ${this.shakeTimer > 0 ? "✅" : "❌"}`;
5966
}
67+
6068
}

Parts/CharacterMovement.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ export class CharacterMovement extends Part {
88
movementType: 'WASD' | 'ArrowKeys' | 'BOTH';
99
input: Input | undefined;
1010

11-
constructor({ name, speed = 5, movementType = 'WASD', input }: { name?: string, speed?: number, movementType?: 'WASD' | 'ArrowKeys' | 'BOTH', input?: Input }) {
12-
super({ name: name || 'CharacterMovement' });
11+
constructor({ speed = 5, movementType = 'WASD', input }: { speed?: number, movementType?: 'WASD' | 'ArrowKeys' | 'BOTH', input?: Input }) {
12+
super({ name: 'CharacterMovement' });
1313
this.speed = speed;
1414
this.movementType = movementType;
15-
this.input = input
15+
this.input = input;
16+
this.type = "CharacterMovement";
1617
}
1718

1819
act(_delta: number): void {
@@ -26,7 +27,6 @@ export class CharacterMovement extends Part {
2627
}
2728

2829
const keys = this.input.downkeys;
29-
3030
let dx = 0;
3131
let dy = 0;
3232

@@ -64,7 +64,8 @@ export class CharacterMovement extends Part {
6464
dx *= Math.SQRT1_2; // 1 / sqrt(2)
6565
dy *= Math.SQRT1_2;
6666
}
67-
68-
transform.move(new Vector(dx * this.speed, dy * this.speed));
67+
if (dx !== 0 || dy !== 0) {
68+
transform.move(new Vector(dx * this.speed, dy * this.speed));
69+
}
6970
}
7071
}

Parts/Children/AnimatedSprite.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export class AnimatedSprite extends Renderer {
1717
disableAntiAliasing: boolean = false; // Option to disable anti-aliasing
1818
webEngine: boolean = false; // Flag to indicate if this is running in a web engine context
1919
onAnimationComplete?: (animationName: string, sprite: AnimatedSprite) => void; // Callback for when an animation completes
20+
spritesheetImage?: string; // Optional image for the spritesheet
2021
constructor({ spritesheet, spritesheetImage, width, height, startingAnimation, disableAntiAliasing = false, onAnimationComplete, webEngine = false }: { spritesheet: string, spritesheetImage?: string, width: number, height: number, startingAnimation?: string, disableAntiAliasing?: boolean, onAnimationComplete?: (animationName: string, sprite: AnimatedSprite) => void, webEngine?: boolean }) {
2122
super({ width, height }); // Call the parent constructor with empty imageSource
2223
this.name = "AnimatedSprite";
@@ -25,11 +26,12 @@ export class AnimatedSprite extends Renderer {
2526
this.width = width;
2627
this.height = height;
2728
this.ready = false;
28-
this.spritesheetImage = spritesheetImage; // Optional image for the spritesheet
29+
2930
this.currentAnimation = startingAnimation || "default";
3031
this.disableAntiAliasing = disableAntiAliasing;
3132
this.onAnimationComplete = onAnimationComplete; // Set the callback for animation completion
3233
this.webEngine = webEngine; // Set the web engine flag
34+
this.type = "AnimatedSprite";
3335
}
3436

3537
async onMount(parent: Part) {

Parts/Children/BoxCollider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export class BoxCollider extends Collider {
1919
this.end = new Vector(width / 2, height / 2);
2020
this.realWorldStart = this.start; // Will be updated in act(), onMount()
2121
this.realWorldEnd = this.end; // Will be updated in act(), onMount()
22+
this.type = "BoxCollider";
2223
}
2324
onMount(parent: Part) {
2425
super.onMount(parent);
@@ -67,7 +68,6 @@ export class BoxCollider extends Collider {
6768
rel.x * cos - rel.y * sin,
6869
rel.x * sin + rel.y * cos
6970
);
70-
console.log(transform);
7171

7272
return transform.worldPosition.add(rotated.add(center));
7373
});

Parts/Children/Button.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import { Input } from "../Input";
55
import { Scene } from "../Scene";
66
import { Renderer } from "./Renderer";
77
import { Sound } from "../Sound";
8+
import { isNamedTupleMember } from "typescript";
89

910
export class Button extends Renderer {
1011
styles?: ButtonStyles;
11-
private isHovered: boolean = false;
12-
private isActive: boolean = false;
12+
isHovered: boolean = false;
13+
isActive: boolean = false;
1314
private onClickHandler: () => void;
1415
clickSound?: Sound;
1516
hoverSound?: Sound;
@@ -23,6 +24,7 @@ export class Button extends Renderer {
2324
this.clickSound = clickSound;
2425
this.hoverSound = hoverSound;
2526
this.activeSound = activeSound;
27+
this.type = "Button";
2628

2729
this.onclick = (event: MouseEvent, input: any) => {
2830
if (this.onClickHandler) {
@@ -62,7 +64,6 @@ export class Button extends Renderer {
6264
}
6365
};
6466
}
65-
6667
onMount(parent: Part) {
6768
super.onMount(parent);
6869
if (!this.sibling("Transform")) {
@@ -74,10 +75,10 @@ export class Button extends Renderer {
7475
// Ensure an Input instance is attached to the scene
7576
if (this.parent instanceof Scene && !this.parent.sibling("Input")) {
7677
this.parent.addChild(new Input({
77-
key: () => {},
78-
keyup: () => {},
79-
mousemove: () => {},
80-
click: () => {},
78+
key: () => { },
79+
keyup: () => { },
80+
mousemove: () => { },
81+
click: () => { },
8182
}));
8283
}
8384

Parts/Children/Collider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ export class Collider extends Part {
66
colliding: boolean = false;
77
collidingWith: Set<Collider> = new Set(); // List of colliding parts
88
constructor() {
9-
super();
10-
this.name = "Collider";
9+
super({ name: "Collider" });
10+
this.type = "Collider";
1111
}
1212

1313
onMount(parent: Part) {

0 commit comments

Comments
 (0)