Skip to content

Commit 1b3b9e4

Browse files
committed
added a little bit more functionality
1 parent bd02921 commit 1b3b9e4

File tree

12 files changed

+471
-404
lines changed

12 files changed

+471
-404
lines changed

Parts/Children/SpriteRender.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import type { Transform } from "./Transform";
66
export class SpriteRender extends Renderer {
77
imageSource: string | null;
88
image: any; // Using any for cross-platform compatibility
9-
constructor({ imageSource, width, height }: { imageSource: string, width: number, height: number }) {
9+
disableAntiAliasing: boolean; // Whether to disable anti-aliasing
10+
constructor({ imageSource, width, height, disableAntiAliasing }: { imageSource: string, width: number, height: number, disableAntiAliasing?: boolean }) {
1011
super({ width, height });
1112
this.name = "SpriteRender";
1213
this.type = "SpriteRender";
1314
this.base = "Renderer";
1415
this.ready = false;
1516
this.imageSource = imageSource;
17+
this.disableAntiAliasing = typeof disableAntiAliasing !== "undefined" ? disableAntiAliasing : false;
1618
this.debugEmoji = "🖼️"; // Default emoji for debugging the sprite render
1719
this.image = new Image() as HTMLImageElement;
1820

@@ -35,7 +37,8 @@ export class SpriteRender extends Renderer {
3537
const clonedSprite = new SpriteRender({
3638
imageSource: this.imageSource!,
3739
width: this.width,
38-
height: this.height
40+
height: this.height,
41+
disableAntiAliasing: this.disableAntiAliasing
3942
});
4043

4144
memo.set(this, clonedSprite);
@@ -76,6 +79,7 @@ export class SpriteRender extends Renderer {
7679
const rotation = transform.rotation;
7780

7881
this.top.context.save();
82+
this.top.context.imageSmoothingEnabled = !this.disableAntiAliasing; // Respect anti-aliasing setting
7983
// Move to the center of the sprite for rotation
8084
this.top.context.translate(position.x, position.y);
8185
this.top.context.rotate(rotation);

Parts/Game.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,16 @@ export class Game extends Part {
195195
this.context.setTransform(1, 0, 0, 1, 0, 0);
196196
this.currentScene.debugTreeRender(this.canvas.width / 2, 10, { x: 10, y: 40 });
197197
this.context.restore();
198+
this.currentScene.preFrame();
198199
this.currentScene.act(delta);
199200
this.currentScene.frameEnd(delta);
200201
this.updateDebugToolTip();
201202
this.context.fillStyle = "red";
202203
this.context.fillRect(this.canvas.width / 2 - 2, this.canvas.height / 2 - 2, 4, 4);
203204
} else {
205+
this.currentScene.preFrame();
204206
this.currentScene.act(delta);
207+
this.currentScene.frameEnd(delta);
205208
}
206209
this._lastUpdateTime = now;
207210
}

Parts/GameObject.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { Part } from "./Part";
44

55
export class GameObject extends Part {
66
layer?: Layer;
7-
constructor({ name }: { name: string }) {
8-
super();
7+
constructor({ name, render }: { name: string, render?: boolean }) {
8+
super({ name, render });
99
this.name = name;
1010
this.debugEmoji = "🕹️"; // Default emoji for debugging the game object
1111
}

Parts/Part.ts

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ export class Part {
3636
warned: Set<string> = new Set(); // Set to track warnings for this part, preventing duplicate warnings
3737
private _childrenByName: { [name: string]: Part } = {}; // For quick access to children by name
3838
private _childrenByType: { [type: string]: Array<Part> } = {}; // For quick access to children by type
39-
constructor({ name }: { name?: string } = {}) {
39+
render: boolean; // Whether this part should be rendered, default true
40+
constructor({ name, render }: { name?: string, render?: boolean } = {}) {
4041
this.id = generateUID();
4142
this.name = name || "New Object";
4243
this.type = "Part";
@@ -45,6 +46,7 @@ export class Part {
4546
this.top = undefined;
4647
this.ready = true;
4748
this.base = "Part";
49+
this.render = typeof render !== "undefined" ? render : true;
4850
this.type = this.constructor.name || "Part"; // Default type is the class name
4951
this.debugEmoji = "🧩"; // Default emoji for debugging
5052
}
@@ -162,9 +164,6 @@ export class Part {
162164
});
163165
}
164166
addChild(child: Part) {
165-
if (child.name == "LightSource") {
166-
console.log(this, child)
167-
}
168167
if (this._childrenByName[child.name]) {
169168
this.top?.warn(`Child with name <${child.name}> already exists in <${this.name}>. Skipping addition. (Child has ID <${child.id}>).`);
170169
return;
@@ -201,7 +200,11 @@ export class Part {
201200
(this as any)[attribute] = value;
202201
return value;
203202
}
204-
203+
preFrame() {
204+
this.childrenArray.forEach(child => {
205+
child.preFrame();
206+
});
207+
}
205208
act(delta: number) {
206209
if (!this.ready) {
207210
return;
@@ -212,6 +215,7 @@ export class Part {
212215
tie.target.attr(tie.targetAttribute, value);
213216
}
214217
});
218+
if (!this.render) return;
215219
this.childrenArray.forEach(child => {
216220
child.act(delta);
217221
});
@@ -408,11 +412,11 @@ export class Part {
408412
// Deep clone children
409413
this._cloneAndAddChildren(clone, memo);
410414

411-
// Deep clone ties, registrations, flats
415+
// Deep clone ties, registrations, flats -- these actually dont need to be cloned, the just need to be re-assigned
412416
// Ties
413417
const clonedTies = new Set<Tie>();
414418
this.ties.forEach(tie => {
415-
const clonedTarget = memo.get(tie.target) || tie.target; // Get cloned target if available, else use original
419+
const clonedTarget = tie.target; // pass reference
416420
clonedTies.add({
417421
target: clonedTarget,
418422
localAttribute: tie.localAttribute,
@@ -425,27 +429,17 @@ export class Part {
425429
const clonedRegistrations: { [key: string]: any } = {};
426430
for (const regKey in this.registrations) {
427431
const regValue = this.registrations[regKey];
428-
if (regValue instanceof Part) {
429-
clonedRegistrations[regKey] = regValue.clone(memo);
430-
} else if (regValue instanceof Vector) {
431-
clonedRegistrations[regKey] = regValue.clone();
432-
} else if (typeof regValue === 'object' && regValue !== null) {
433-
clonedRegistrations[regKey] = { ...regValue }; // Shallow copy for now, can be made deeper if needed
434-
} else {
435-
clonedRegistrations[regKey] = regValue;
436-
}
432+
clonedRegistrations[regKey] = regValue; // Pass reference
437433
}
438434
clone.registrations = clonedRegistrations;
439-
440435
// Flats
441436
const clonedFlats = { colliders: [] as Collider[] };
442437
if (this.flats.colliders) {
443438
clonedFlats.colliders = this.flats.colliders.map((collider: Collider) => {
444-
return collider.clone(memo);
439+
return collider; // pass reference
445440
});
446441
}
447442
clone.flats = clonedFlats;
448-
449443
// Copy other simple properties that are not handled by constructor or special logic
450444
clone.id = generateUID(); // Generate new ID
451445
clone.name = this.name; // Copy name
@@ -455,9 +449,9 @@ export class Part {
455449
clone._layoutWidth = this._layoutWidth; // Copy layout width
456450
clone._superficialWidth = this._superficialWidth; // Copy superficial width
457451
clone._superficialHeight = this._superficialHeight; // Copy superficial height
452+
clone.base = this.base; // Copy base
458453
clone.warned = new Set(this.warned); // Copy warned set
459454

460-
461455
return clone;
462456
}
463457

Parts/Scene.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@ import { Part } from "./Part";
55

66
export class Scene extends Part {
77
activeCamera: Camera | null = null; // The active camera for this scene
8-
backgroundColor: string; // Background color of the scene
9-
constructor({ name, backgroundColor }: { name: string, backgroundColor?: string } = { name: "Scene" }) {
8+
constructor({ name }: { name: string } = { name: "Scene" }) {
109
super();
1110
this.name = name;
1211
this.debugEmoji = "🏞️"; // Default emoji for debugging the scene
13-
this.backgroundColor = backgroundColor || "#000"; // Default background color
1412
}
1513
clone(memo = new Map()): this {
1614
if (memo.has(this)) {
@@ -19,7 +17,6 @@ export class Scene extends Part {
1917

2018
const clonedScene = new Scene({
2119
name: this.name,
22-
backgroundColor: this.backgroundColor
2320
});
2421

2522
memo.set(this, clonedScene);
@@ -56,13 +53,6 @@ export class Scene extends Part {
5653
throw new Error("Game instance must have a canvas element.");
5754
}
5855

59-
// Draw background BEFORE applying camera transformations
60-
// This ensures the background covers the entire screen regardless of camera position
61-
if (this.backgroundColor) {
62-
this.top.context.fillStyle = this.backgroundColor;
63-
this.top.context.fillRect(0, 0, this.top.canvas.width, this.top.canvas.height);
64-
}
65-
6656
// Now apply camera transformations for world space objects
6757
if (this.activeCamera && this.top instanceof Game) {
6858
const camera = this.activeCamera;

docs/custom-classes.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,20 @@ export interface PropertyDefinition {
5252
fileType?: 'image' | 'audio' | 'video' | 'json'; // For the 'file' type
5353
options?: string[]; // For enum type. Enum only accepts string as subtype
5454
dontShow?: boolean; // If true, this property will not show up in the editor.
55+
tertiaryType?: string; // For defining the type of Parts when Part is a subtype of main type List
5556
}
5657
```
5758

59+
Examples:
60+
```js
61+
{ type: "number", default: 50, description: "How fast the character moves" },
62+
{ type: "boolean", default: false, description: "Whether the character is on offensive or defensive" },
63+
{ type: "list", subType: "number", default: [0.2, 1, 1.5], description: "Crawl speed, walk speed, run speed multipliers" },
64+
{ type: "enum", options: ["CRAWL", "WALK", "RUN"], description: "The starting state of the character" },
65+
{ type: "list", subType: "ParT", tertiaryType: "GameObject", description: "Target game objects- the character wins when he reaches any one of these" },
66+
{ type: "boolean", default: true, dontShow: true, description: "A hidden property that changes the way that sprites are loaded if in the web editor" }
67+
```
68+
5869
#### Setting `default`
5970

6071
As a general rule, follow the type of your property. Eg:

0 commit comments

Comments
 (0)