@guinetik/gcanvas 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gcanvas.es.js +25656 -0
- package/dist/gcanvas.es.min.js +1 -0
- package/dist/gcanvas.umd.js +1 -0
- package/dist/gcanvas.umd.min.js +1 -0
- package/package.json +23 -6
- package/src/game/objects/index.js +1 -0
- package/src/game/objects/spritesheet.js +260 -0
- package/src/game/ui/theme.js +6 -0
- package/src/io/keys.js +9 -1
- package/src/math/boolean.js +481 -0
- package/src/math/index.js +1 -0
- package/.github/workflows/release.yaml +0 -70
- package/.jshintrc +0 -4
- package/.vscode/settings.json +0 -22
- package/CLAUDE.md +0 -310
- package/blackhole.jpg +0 -0
- package/demo.png +0 -0
- package/demos/CNAME +0 -1
- package/demos/animations.html +0 -31
- package/demos/basic.html +0 -38
- package/demos/baskara.html +0 -31
- package/demos/bezier.html +0 -35
- package/demos/beziersignature.html +0 -29
- package/demos/blackhole.html +0 -28
- package/demos/blob.html +0 -35
- package/demos/coordinates.html +0 -698
- package/demos/cube3d.html +0 -23
- package/demos/demos.css +0 -303
- package/demos/dino.html +0 -42
- package/demos/easing.html +0 -28
- package/demos/events.html +0 -195
- package/demos/fluent.html +0 -647
- package/demos/fluid-simple.html +0 -22
- package/demos/fluid.html +0 -37
- package/demos/fractals.html +0 -36
- package/demos/gameobjects.html +0 -626
- package/demos/genart.html +0 -26
- package/demos/gendream.html +0 -26
- package/demos/group.html +0 -36
- package/demos/home.html +0 -587
- package/demos/index.html +0 -376
- package/demos/isometric.html +0 -34
- package/demos/js/animations.js +0 -452
- package/demos/js/basic.js +0 -204
- package/demos/js/baskara.js +0 -751
- package/demos/js/bezier.js +0 -692
- package/demos/js/beziersignature.js +0 -241
- package/demos/js/blackhole/accretiondisk.obj.js +0 -379
- package/demos/js/blackhole/blackhole.obj.js +0 -318
- package/demos/js/blackhole/index.js +0 -409
- package/demos/js/blackhole/particle.js +0 -56
- package/demos/js/blackhole/starfield.obj.js +0 -218
- package/demos/js/blob.js +0 -2276
- package/demos/js/coordinates.js +0 -840
- package/demos/js/cube3d.js +0 -789
- package/demos/js/dino.js +0 -1420
- package/demos/js/easing.js +0 -477
- package/demos/js/fluent.js +0 -183
- package/demos/js/fluid-simple.js +0 -253
- package/demos/js/fluid.js +0 -527
- package/demos/js/fractals.js +0 -931
- package/demos/js/fractalworker.js +0 -93
- package/demos/js/gameobjects.js +0 -176
- package/demos/js/genart.js +0 -268
- package/demos/js/gendream.js +0 -209
- package/demos/js/group.js +0 -140
- package/demos/js/info-toggle.js +0 -25
- package/demos/js/isometric.js +0 -863
- package/demos/js/kerr.js +0 -1556
- package/demos/js/lavalamp.js +0 -590
- package/demos/js/layout.js +0 -354
- package/demos/js/mondrian.js +0 -285
- package/demos/js/opacity.js +0 -275
- package/demos/js/painter.js +0 -484
- package/demos/js/particles-showcase.js +0 -514
- package/demos/js/particles.js +0 -299
- package/demos/js/patterns.js +0 -397
- package/demos/js/penrose/artifact.js +0 -69
- package/demos/js/penrose/blackhole.js +0 -121
- package/demos/js/penrose/constants.js +0 -73
- package/demos/js/penrose/game.js +0 -943
- package/demos/js/penrose/lore.js +0 -278
- package/demos/js/penrose/penrosescene.js +0 -892
- package/demos/js/penrose/ship.js +0 -216
- package/demos/js/penrose/sounds.js +0 -211
- package/demos/js/penrose/voidparticle.js +0 -55
- package/demos/js/penrose/voidscene.js +0 -258
- package/demos/js/penrose/voidship.js +0 -144
- package/demos/js/penrose/wormhole.js +0 -46
- package/demos/js/pipeline.js +0 -555
- package/demos/js/plane3d.js +0 -256
- package/demos/js/platformer.js +0 -1579
- package/demos/js/scene.js +0 -304
- package/demos/js/scenes.js +0 -320
- package/demos/js/schrodinger.js +0 -410
- package/demos/js/schwarzschild.js +0 -1023
- package/demos/js/shapes.js +0 -628
- package/demos/js/space/alien.js +0 -171
- package/demos/js/space/boom.js +0 -98
- package/demos/js/space/boss.js +0 -353
- package/demos/js/space/buff.js +0 -73
- package/demos/js/space/bullet.js +0 -102
- package/demos/js/space/constants.js +0 -85
- package/demos/js/space/game.js +0 -1884
- package/demos/js/space/hud.js +0 -112
- package/demos/js/space/laserbeam.js +0 -179
- package/demos/js/space/lightning.js +0 -277
- package/demos/js/space/minion.js +0 -192
- package/demos/js/space/missile.js +0 -212
- package/demos/js/space/player.js +0 -430
- package/demos/js/space/powerup.js +0 -90
- package/demos/js/space/starfield.js +0 -58
- package/demos/js/space/starpower.js +0 -90
- package/demos/js/spacetime.js +0 -559
- package/demos/js/sphere3d.js +0 -229
- package/demos/js/sprite.js +0 -473
- package/demos/js/svgtween.js +0 -204
- package/demos/js/tde/accretiondisk.js +0 -471
- package/demos/js/tde/blackhole.js +0 -219
- package/demos/js/tde/blackholescene.js +0 -209
- package/demos/js/tde/config.js +0 -59
- package/demos/js/tde/index.js +0 -820
- package/demos/js/tde/jets.js +0 -290
- package/demos/js/tde/lensedstarfield.js +0 -154
- package/demos/js/tde/tdestar.js +0 -297
- package/demos/js/tde/tidalstream.js +0 -372
- package/demos/js/tde_old/blackhole.obj.js +0 -354
- package/demos/js/tde_old/debris.obj.js +0 -791
- package/demos/js/tde_old/flare.obj.js +0 -239
- package/demos/js/tde_old/index.js +0 -448
- package/demos/js/tde_old/star.obj.js +0 -812
- package/demos/js/tiles.js +0 -312
- package/demos/js/tweendemo.js +0 -79
- package/demos/js/visibility.js +0 -102
- package/demos/kerr.html +0 -28
- package/demos/lavalamp.html +0 -27
- package/demos/layouts.html +0 -37
- package/demos/logo.svg +0 -4
- package/demos/loop.html +0 -84
- package/demos/mondrian.html +0 -32
- package/demos/og_image.png +0 -0
- package/demos/opacity.html +0 -36
- package/demos/painter.html +0 -39
- package/demos/particles-showcase.html +0 -28
- package/demos/particles.html +0 -24
- package/demos/patterns.html +0 -33
- package/demos/penrose-game.html +0 -31
- package/demos/pipeline.html +0 -737
- package/demos/plane3d.html +0 -24
- package/demos/platformer.html +0 -43
- package/demos/scene.html +0 -33
- package/demos/scenes.html +0 -96
- package/demos/schrodinger.html +0 -27
- package/demos/schwarzschild.html +0 -27
- package/demos/shapes.html +0 -16
- package/demos/space.html +0 -85
- package/demos/spacetime.html +0 -27
- package/demos/sphere3d.html +0 -24
- package/demos/sprite.html +0 -18
- package/demos/svgtween.html +0 -29
- package/demos/tde.html +0 -28
- package/demos/tiles.html +0 -28
- package/demos/transforms.html +0 -400
- package/demos/tween.html +0 -45
- package/demos/visibility.html +0 -33
- package/docs/README.md +0 -230
- package/docs/api/FluidSystem.md +0 -173
- package/docs/concepts/architecture-overview.md +0 -204
- package/docs/concepts/coordinate-system.md +0 -384
- package/docs/concepts/lifecycle.md +0 -255
- package/docs/concepts/rendering-pipeline.md +0 -279
- package/docs/concepts/shapes-vs-gameobjects.md +0 -187
- package/docs/concepts/tde-zorder.md +0 -106
- package/docs/concepts/two-layer-architecture.md +0 -229
- package/docs/fluid-dynamics.md +0 -99
- package/docs/getting-started/first-game.md +0 -354
- package/docs/getting-started/hello-world.md +0 -269
- package/docs/getting-started/installation.md +0 -175
- package/docs/modules/collision/README.md +0 -453
- package/docs/modules/fluent/README.md +0 -1075
- package/docs/modules/game/README.md +0 -303
- package/docs/modules/isometric-camera.md +0 -210
- package/docs/modules/isometric.md +0 -275
- package/docs/modules/painter/README.md +0 -328
- package/docs/modules/particle/README.md +0 -559
- package/docs/modules/shapes/README.md +0 -221
- package/docs/modules/shapes/base/euclidian.md +0 -123
- package/docs/modules/shapes/base/geometry2d.md +0 -204
- package/docs/modules/shapes/base/renderable.md +0 -215
- package/docs/modules/shapes/base/shape.md +0 -262
- package/docs/modules/shapes/base/transformable.md +0 -243
- package/docs/modules/shapes/hierarchy.md +0 -218
- package/docs/modules/state/README.md +0 -577
- package/docs/modules/util/README.md +0 -99
- package/docs/modules/util/camera3d.md +0 -412
- package/docs/modules/util/scene3d.md +0 -395
- package/index.html +0 -17
- package/jsdoc.json +0 -50
- package/scripts/build-demo.js +0 -69
- package/scripts/bundle4llm.js +0 -276
- package/scripts/clearconsole.js +0 -48
- package/test/math/orbital.test.js +0 -61
- package/test/math/tensor.test.js +0 -114
- package/test/particle/emitter.test.js +0 -204
- package/test/particle/particle-system.test.js +0 -310
- package/test/particle/particle.test.js +0 -116
- package/test/particle/updaters.test.js +0 -386
- package/test/setup.js +0 -120
- package/test/shapes/euclidian.test.js +0 -44
- package/test/shapes/geometry.test.js +0 -86
- package/test/shapes/group.test.js +0 -86
- package/test/shapes/rectangle.test.js +0 -64
- package/test/shapes/transform.test.js +0 -379
- package/test/util/camera3d.test.js +0 -428
- package/test/util/scene3d.test.js +0 -352
- package/vite.config.js +0 -50
- package/vitest.config.js +0 -13
package/demos/js/scene.js
DELETED
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Game,
|
|
3
|
-
Scene,
|
|
4
|
-
Button,
|
|
5
|
-
FPSCounter,
|
|
6
|
-
VerticalLayout,
|
|
7
|
-
Rectangle,
|
|
8
|
-
Group,
|
|
9
|
-
applyDraggable,
|
|
10
|
-
Painter,
|
|
11
|
-
Tween,
|
|
12
|
-
Easing,
|
|
13
|
-
Random,
|
|
14
|
-
GameObjectShapeWrapper,
|
|
15
|
-
Position,
|
|
16
|
-
} from "../../src/index.js";
|
|
17
|
-
// Demo Game with Scenes
|
|
18
|
-
export class DemoGame extends Game {
|
|
19
|
-
constructor(canvas) {
|
|
20
|
-
super(canvas);
|
|
21
|
-
this.MARGIN = 0;
|
|
22
|
-
this.enableFluidSize();
|
|
23
|
-
this.backgroundColor = "white";
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
getResponsiveConfig() {
|
|
27
|
-
const isNarrow = this.width < 500;
|
|
28
|
-
return {
|
|
29
|
-
buttonWidth: isNarrow ? 120 : 150,
|
|
30
|
-
layerCount: isNarrow ? 25 : 50,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
init() {
|
|
35
|
-
super.init();
|
|
36
|
-
const config = this.getResponsiveConfig();
|
|
37
|
-
this.currentButtonWidth = config.buttonWidth;
|
|
38
|
-
|
|
39
|
-
this.scene = new Scene(this, { debug: true, debugColor: "black" });
|
|
40
|
-
this.ui = new Scene(this, {
|
|
41
|
-
debug: true,
|
|
42
|
-
anchor: Position.BOTTOM_LEFT,
|
|
43
|
-
anchorRelative: this.scene,
|
|
44
|
-
});
|
|
45
|
-
this.pipeline.add(this.scene); // scene below
|
|
46
|
-
this.pipeline.add(this.ui); // UI on top
|
|
47
|
-
this.pipeline.add(
|
|
48
|
-
new FPSCounter(this, { anchor: "bottom-right", color: "black" })
|
|
49
|
-
);
|
|
50
|
-
this.buttons = this.ui.add(
|
|
51
|
-
new VerticalLayout(this, {
|
|
52
|
-
debug: true,
|
|
53
|
-
debugColor: "black",
|
|
54
|
-
spacing: 10,
|
|
55
|
-
padding: 10,
|
|
56
|
-
})
|
|
57
|
-
);
|
|
58
|
-
this.buttons.width = config.buttonWidth;
|
|
59
|
-
this.buttons.height = 200;
|
|
60
|
-
// Small demo of Random functions
|
|
61
|
-
let random = Random.symmetric;
|
|
62
|
-
const options = [
|
|
63
|
-
Random.symmetric,
|
|
64
|
-
Random.centered,
|
|
65
|
-
Random.gaussian,
|
|
66
|
-
Random.radial,
|
|
67
|
-
];
|
|
68
|
-
this.buttons.add(
|
|
69
|
-
this.createButton("➕ Add Layer", () => this.addLayer(random))
|
|
70
|
-
);
|
|
71
|
-
this.buttons.add(this.createButton("❎ Clear", () => this.scene.clear()));
|
|
72
|
-
this.buttons.add(
|
|
73
|
-
this.createButton("🎲 Randomize", () => {
|
|
74
|
-
this.scene.children.forEach((layer) => {
|
|
75
|
-
layer.scaleX = layer.scaleY = layer.scaleTime = 0;
|
|
76
|
-
layer.random = random;
|
|
77
|
-
layer.randomize();
|
|
78
|
-
});
|
|
79
|
-
})
|
|
80
|
-
);
|
|
81
|
-
const rollBtn = this.createButton("🔄️" + random.name, () => {
|
|
82
|
-
random = Random.pickOther(options, random);
|
|
83
|
-
console.log(random.name);
|
|
84
|
-
rollBtn.text = "🔄️" + random.name;
|
|
85
|
-
});
|
|
86
|
-
this.buttons.add(rollBtn);
|
|
87
|
-
// Add random layers
|
|
88
|
-
for (let i = 0; i < config.layerCount; i++) {
|
|
89
|
-
this.addLayer(random, i);
|
|
90
|
-
}
|
|
91
|
-
this.positionScene();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
createButton(text, onClick) {
|
|
95
|
-
return new Button(this, {
|
|
96
|
-
text: text,
|
|
97
|
-
width: this.currentButtonWidth,
|
|
98
|
-
textAlign: "left",
|
|
99
|
-
onClick: onClick,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
#prevWidth = 0;
|
|
104
|
-
#prevHeight = 0;
|
|
105
|
-
|
|
106
|
-
positionScene() {
|
|
107
|
-
this.scene.width = this.width - this.MARGIN * 2;
|
|
108
|
-
this.scene.height = this.height - this.MARGIN * 2;
|
|
109
|
-
this.scene.x = this.width / 2;
|
|
110
|
-
this.scene.y = this.height / 2;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
update(dt) {
|
|
114
|
-
this.positionScene();
|
|
115
|
-
//
|
|
116
|
-
if (this.ui.width !== this.buttons.width + 10) {
|
|
117
|
-
this.ui.width = this.buttons.width + 10;
|
|
118
|
-
}
|
|
119
|
-
if (this.ui.height !== this.buttons.height + 10) {
|
|
120
|
-
this.ui.height = this.buttons.height + 10;
|
|
121
|
-
}
|
|
122
|
-
super.update(dt);
|
|
123
|
-
if (this.#prevWidth !== this.width || this.#prevHeight !== this.height) {
|
|
124
|
-
this.scene.markBoundsDirty();
|
|
125
|
-
}
|
|
126
|
-
this.#prevWidth = this.scene.width;
|
|
127
|
-
this.#prevHeight = this.scene.height;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
addLayer(random, i) {
|
|
131
|
-
const layer = new LayerBox(this, this.scene, {}, random);
|
|
132
|
-
this.scene.add(layer);
|
|
133
|
-
setTimeout(layer.randomize.bind(layer), 50 * i);
|
|
134
|
-
return layer;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
onResize() {
|
|
138
|
-
if (!this.buttons) return;
|
|
139
|
-
|
|
140
|
-
const config = this.getResponsiveConfig();
|
|
141
|
-
|
|
142
|
-
// Update button widths if changed
|
|
143
|
-
if (this.currentButtonWidth !== config.buttonWidth) {
|
|
144
|
-
this.currentButtonWidth = config.buttonWidth;
|
|
145
|
-
this.buttons.transform.width(config.buttonWidth);
|
|
146
|
-
|
|
147
|
-
// Update each button's width
|
|
148
|
-
if (this.buttons.children) {
|
|
149
|
-
this.buttons.children.forEach((btn) => {
|
|
150
|
-
if (btn.transform) {
|
|
151
|
-
btn.transform.width(config.buttonWidth);
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
this.buttons.markBoundsDirty();
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
this.positionScene();
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
// LayerBox class
|
|
162
|
-
class LayerBox extends GameObjectShapeWrapper {
|
|
163
|
-
constructor(game, scene, options, random = Random.symmetric) {
|
|
164
|
-
const group = new Group();
|
|
165
|
-
super(game, group, options);
|
|
166
|
-
this.interactive = true;
|
|
167
|
-
this.scene = scene;
|
|
168
|
-
this.random = random;
|
|
169
|
-
this.group = group;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
init() {
|
|
173
|
-
// Create a random rectangle
|
|
174
|
-
const size = 100;
|
|
175
|
-
const color = Painter.colors.randomColorHSL();
|
|
176
|
-
// Create a rectangle and group
|
|
177
|
-
this.rect = new Rectangle({
|
|
178
|
-
width: size,
|
|
179
|
-
height: size,
|
|
180
|
-
color: color,
|
|
181
|
-
stroke: "white",
|
|
182
|
-
lineWidth: 2,
|
|
183
|
-
});
|
|
184
|
-
this.width = size;
|
|
185
|
-
this.height = size;
|
|
186
|
-
this.group.add(this.rect);
|
|
187
|
-
//
|
|
188
|
-
this.startScale = 0;
|
|
189
|
-
this.targetScale = 1;
|
|
190
|
-
this.scaleTime = 0;
|
|
191
|
-
this.scaleDuration = 1; // seconds
|
|
192
|
-
//
|
|
193
|
-
this.on("mouseover", () => {
|
|
194
|
-
if (!this.scene.dragging) {
|
|
195
|
-
this.startScale = this.scaleX;
|
|
196
|
-
this.targetScale = 1.3;
|
|
197
|
-
this.scaleTime = 0;
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
this.on("mouseout", () => {
|
|
201
|
-
if (!this.dragging) {
|
|
202
|
-
this.startScale = this.scaleX;
|
|
203
|
-
this.scaleTime = 0;
|
|
204
|
-
this.targetScale = 1;
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
//
|
|
208
|
-
this.applyDraggable();
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
applyDraggable() {
|
|
212
|
-
applyDraggable(this, {
|
|
213
|
-
onDragStart: () => {
|
|
214
|
-
console.log("Drag start", this.constructor.name);
|
|
215
|
-
this.scene.dragging = true;
|
|
216
|
-
this.scene.bringToFront(this);
|
|
217
|
-
this.targetScale = 1.5;
|
|
218
|
-
this.scaleTime = 0;
|
|
219
|
-
this.shadowBox();
|
|
220
|
-
},
|
|
221
|
-
onDragEnd: () => {
|
|
222
|
-
console.log("Drag end", this.constructor.name);
|
|
223
|
-
//this.scene.bringToFront(this);
|
|
224
|
-
this.scaleTime = 0;
|
|
225
|
-
this.targetScale = 1.0;
|
|
226
|
-
this.clearShadowBox();
|
|
227
|
-
this.scene.dragging = false;
|
|
228
|
-
},
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
shadowBox() {
|
|
233
|
-
if (this.rect.shadorColor == null) {
|
|
234
|
-
this.rect.shadowColor = "rgba(0, 0, 0, 0.5)";
|
|
235
|
-
this.rect.shadowBlur = 20;
|
|
236
|
-
this.rect.shadowOffsetX = 10;
|
|
237
|
-
this.rect.shadowOffsetY = 10;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
clearShadowBox() {
|
|
242
|
-
this.rect.shadowColor = null;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
randomize() {
|
|
246
|
-
const param = {
|
|
247
|
-
symmetric: 1,
|
|
248
|
-
centered: 500,
|
|
249
|
-
gaussian: Math.random() * this.parent.width,
|
|
250
|
-
radial: this.parent.width / 3,
|
|
251
|
-
};
|
|
252
|
-
const { x, y } = this.random(
|
|
253
|
-
-this.parent.width / 2,
|
|
254
|
-
-this.parent.height / 2,
|
|
255
|
-
this.parent.width,
|
|
256
|
-
this.parent.height,
|
|
257
|
-
param[this.random.name]
|
|
258
|
-
);
|
|
259
|
-
// console.log(x, y);
|
|
260
|
-
this.x = x;
|
|
261
|
-
this.y = y;
|
|
262
|
-
this.scaleX = this.scaleY = 0;
|
|
263
|
-
this.scaleTime = 0;
|
|
264
|
-
this.targetScale = 1;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
update(dt) {
|
|
268
|
-
// Smooth scale animation
|
|
269
|
-
// Animate scale using bounce
|
|
270
|
-
if (this.scaleTime < this.scaleDuration) {
|
|
271
|
-
this.scaleTime += dt;
|
|
272
|
-
const t = Math.min(this.scaleTime / this.scaleDuration, 1);
|
|
273
|
-
const eased = Easing.easeOutElastic(t);
|
|
274
|
-
const scale = Tween.lerp(this.startScale, this.targetScale, eased);
|
|
275
|
-
this.scaleX = this.scaleY = scale;
|
|
276
|
-
this.tweening = true;
|
|
277
|
-
} else {
|
|
278
|
-
this.tweening = false;
|
|
279
|
-
}
|
|
280
|
-
//if (this.dragging) {
|
|
281
|
-
// Set the object's own half-dimensions
|
|
282
|
-
const halfW = 50;
|
|
283
|
-
const halfH = 50;
|
|
284
|
-
|
|
285
|
-
// Calculate the bounds within the parent's coordinate space
|
|
286
|
-
// This creates a "safe zone" that's 10px from the edge
|
|
287
|
-
const parentHalfWidth = this.parent.width / 2;
|
|
288
|
-
const parentHalfHeight = this.parent.height / 2;
|
|
289
|
-
|
|
290
|
-
// Maximum boundaries (accounting for the object's size and parent position)
|
|
291
|
-
const maxX = parentHalfWidth - halfW - 10;
|
|
292
|
-
const maxY = parentHalfHeight - halfH - 10;
|
|
293
|
-
|
|
294
|
-
// Minimum boundaries (accounting for the object's size and parent position)
|
|
295
|
-
const minX = -parentHalfWidth + halfW + 10;
|
|
296
|
-
const minY = -parentHalfHeight + halfH + 10;
|
|
297
|
-
|
|
298
|
-
// Clamp to parent bounds
|
|
299
|
-
this.x = Math.max(minX, Math.min(maxX, this.x));
|
|
300
|
-
this.y = Math.max(minY, Math.min(maxY, this.y));
|
|
301
|
-
//}
|
|
302
|
-
super.update(dt);
|
|
303
|
-
}
|
|
304
|
-
}
|
package/demos/js/scenes.js
DELETED
|
@@ -1,320 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Game,
|
|
3
|
-
GameObject,
|
|
4
|
-
Scene,
|
|
5
|
-
Rectangle,
|
|
6
|
-
Circle,
|
|
7
|
-
Star,
|
|
8
|
-
Triangle,
|
|
9
|
-
TextShape,
|
|
10
|
-
Group,
|
|
11
|
-
FPSCounter,
|
|
12
|
-
Motion,
|
|
13
|
-
Easing,
|
|
14
|
-
Painter,
|
|
15
|
-
} from "../../src/index";
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Helper class to wrap a Shape in a GameObject for use in Scenes.
|
|
19
|
-
* Scenes expect GameObjects, not raw Shapes.
|
|
20
|
-
*/
|
|
21
|
-
class ShapeWrapper extends GameObject {
|
|
22
|
-
constructor(game, shape) {
|
|
23
|
-
super(game);
|
|
24
|
-
this.shape = shape;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
draw() {
|
|
28
|
-
super.draw();
|
|
29
|
-
this.shape.render();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Utility function to wrap a shape in a GameObject
|
|
35
|
-
*/
|
|
36
|
-
function wrapShape(game, shape) {
|
|
37
|
-
return new ShapeWrapper(game, shape);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* SceneDemo Game
|
|
42
|
-
* Demonstrates Scene capabilities: nesting, transforms, and z-ordering
|
|
43
|
-
*/
|
|
44
|
-
export class MyGame extends Game {
|
|
45
|
-
constructor(canvas) {
|
|
46
|
-
super(canvas);
|
|
47
|
-
this.enableFluidSize();
|
|
48
|
-
this.backgroundColor = "black";
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
init() {
|
|
52
|
-
super.init();
|
|
53
|
-
|
|
54
|
-
// Main container scene (centered)
|
|
55
|
-
this.mainScene = new Scene(this, {
|
|
56
|
-
width: 600,
|
|
57
|
-
height: 400,
|
|
58
|
-
debug: false,
|
|
59
|
-
debugColor: "#ff00ff",
|
|
60
|
-
anchor: "center"
|
|
61
|
-
});
|
|
62
|
-
this.pipeline.add(this.mainScene);
|
|
63
|
-
|
|
64
|
-
// Add demo scenes
|
|
65
|
-
this.mainScene.add(new TransformingSceneDemo(this));
|
|
66
|
-
this.mainScene.add(new NestedSceneDemo(this));
|
|
67
|
-
this.mainScene.add(new ZOrderDemo(this));
|
|
68
|
-
|
|
69
|
-
// FPS counter
|
|
70
|
-
this.pipeline.add(new FPSCounter(this, { anchor: "bottom-right" }));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
onResize() {
|
|
74
|
-
if (this.mainScene) {
|
|
75
|
-
// Adjust main scene to fit screen
|
|
76
|
-
this.mainScene.width = Math.min(this.width - 40, 800);
|
|
77
|
-
this.mainScene.height = Math.min(this.height - 80, 500);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Demo 1: Scene with animated transforms
|
|
84
|
-
* Shows rotation and scaling applied to a scene with children
|
|
85
|
-
*/
|
|
86
|
-
class TransformingSceneDemo extends GameObject {
|
|
87
|
-
constructor(game) {
|
|
88
|
-
super(game);
|
|
89
|
-
|
|
90
|
-
// Create a scene that will be transformed
|
|
91
|
-
this.scene = new Scene(game, {
|
|
92
|
-
width: 120,
|
|
93
|
-
height: 120,
|
|
94
|
-
debug: false,
|
|
95
|
-
debugColor: "#ff00ff"
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// Position using transform API
|
|
99
|
-
this.scene.transform.position(-200, -80);
|
|
100
|
-
|
|
101
|
-
// Add shapes to the scene
|
|
102
|
-
const rect = new Rectangle({
|
|
103
|
-
width: 40,
|
|
104
|
-
height: 40,
|
|
105
|
-
color: "#e94560",
|
|
106
|
-
stroke: "#fff",
|
|
107
|
-
lineWidth: 2
|
|
108
|
-
});
|
|
109
|
-
rect.transform.position(-25, -25);
|
|
110
|
-
|
|
111
|
-
const circle = new Circle(15, {
|
|
112
|
-
color: "#00d9ff",
|
|
113
|
-
stroke: "#fff",
|
|
114
|
-
lineWidth: 2
|
|
115
|
-
});
|
|
116
|
-
circle.transform.position(25, 25);
|
|
117
|
-
|
|
118
|
-
const star = new Star(12, 5, 0.5, {
|
|
119
|
-
color: "#ffc107",
|
|
120
|
-
stroke: "#fff",
|
|
121
|
-
lineWidth: 1
|
|
122
|
-
});
|
|
123
|
-
star.transform.position(25, -25);
|
|
124
|
-
|
|
125
|
-
// Add shapes via wrapper
|
|
126
|
-
this.scene.add(wrapShape(game, rect));
|
|
127
|
-
this.scene.add(wrapShape(game, circle));
|
|
128
|
-
this.scene.add(wrapShape(game, star));
|
|
129
|
-
|
|
130
|
-
// Label
|
|
131
|
-
this.label = new TextShape("Scene Transforms", {
|
|
132
|
-
x: -200,
|
|
133
|
-
y: -150,
|
|
134
|
-
font: "bold 12px monospace",
|
|
135
|
-
color: "#fff",
|
|
136
|
-
align: "center"
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
this.elapsed = 0;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
update(dt) {
|
|
143
|
-
super.update(dt);
|
|
144
|
-
this.elapsed += dt;
|
|
145
|
-
|
|
146
|
-
// Animate the scene's transforms
|
|
147
|
-
this.scene.transform
|
|
148
|
-
.rotation(this.elapsed * 30)
|
|
149
|
-
.scale(0.8 + Math.sin(this.elapsed * 2) * 0.2);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
draw() {
|
|
153
|
-
super.draw();
|
|
154
|
-
this.scene.render();
|
|
155
|
-
this.label.render();
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Demo 2: Nested Scenes
|
|
161
|
-
* Shows scenes containing other scenes
|
|
162
|
-
*/
|
|
163
|
-
class NestedSceneDemo extends GameObject {
|
|
164
|
-
constructor(game) {
|
|
165
|
-
super(game);
|
|
166
|
-
|
|
167
|
-
// Outer scene
|
|
168
|
-
this.outerScene = new Scene(game, {
|
|
169
|
-
width: 150,
|
|
170
|
-
height: 150,
|
|
171
|
-
debug: false,
|
|
172
|
-
debugColor: "#ff00ff"
|
|
173
|
-
});
|
|
174
|
-
this.outerScene.transform.position(0, -80);
|
|
175
|
-
|
|
176
|
-
// Inner scene (nested inside outer)
|
|
177
|
-
this.innerScene = new Scene(game, {
|
|
178
|
-
width: 80,
|
|
179
|
-
height: 80,
|
|
180
|
-
debug: false,
|
|
181
|
-
debugColor: "#00ffff"
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
// Add shapes to inner scene
|
|
185
|
-
const innerRect = new Rectangle({
|
|
186
|
-
width: 30,
|
|
187
|
-
height: 30,
|
|
188
|
-
color: "#7bed9f",
|
|
189
|
-
stroke: "#fff",
|
|
190
|
-
lineWidth: 2
|
|
191
|
-
});
|
|
192
|
-
this.innerScene.add(wrapShape(game, innerRect));
|
|
193
|
-
|
|
194
|
-
// Add inner scene to outer
|
|
195
|
-
this.outerScene.add(this.innerScene);
|
|
196
|
-
|
|
197
|
-
// Add corner markers to outer scene
|
|
198
|
-
const corners = [
|
|
199
|
-
{ x: -50, y: -50 },
|
|
200
|
-
{ x: 50, y: -50 },
|
|
201
|
-
{ x: 50, y: 50 },
|
|
202
|
-
{ x: -50, y: 50 }
|
|
203
|
-
];
|
|
204
|
-
corners.forEach((pos, i) => {
|
|
205
|
-
const marker = new Circle(8, {
|
|
206
|
-
color: ["#ff6b6b", "#ffc107", "#00d9ff", "#7bed9f"][i],
|
|
207
|
-
stroke: "#fff",
|
|
208
|
-
lineWidth: 1
|
|
209
|
-
});
|
|
210
|
-
marker.transform.position(pos.x, pos.y);
|
|
211
|
-
this.outerScene.add(wrapShape(game, marker));
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
// Label
|
|
215
|
-
this.label = new TextShape("Nested Scenes", {
|
|
216
|
-
x: 0,
|
|
217
|
-
y: -150,
|
|
218
|
-
font: "bold 12px monospace",
|
|
219
|
-
color: "#fff",
|
|
220
|
-
align: "center"
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
this.elapsed = 0;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
update(dt) {
|
|
227
|
-
super.update(dt);
|
|
228
|
-
this.elapsed += dt;
|
|
229
|
-
|
|
230
|
-
// Outer scene rotates slowly
|
|
231
|
-
this.outerScene.transform.rotation(this.elapsed * 20);
|
|
232
|
-
|
|
233
|
-
// Inner scene counter-rotates and pulses
|
|
234
|
-
this.innerScene.transform
|
|
235
|
-
.rotation(-this.elapsed * 60)
|
|
236
|
-
.scale(0.9 + Math.sin(this.elapsed * 3) * 0.2);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
draw() {
|
|
240
|
-
super.draw();
|
|
241
|
-
this.outerScene.render();
|
|
242
|
-
this.label.render();
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Demo 3: Z-Ordering in Scenes
|
|
248
|
-
* Shows bring to front / send to back functionality
|
|
249
|
-
*/
|
|
250
|
-
class ZOrderDemo extends GameObject {
|
|
251
|
-
constructor(game) {
|
|
252
|
-
super(game);
|
|
253
|
-
|
|
254
|
-
this.scene = new Scene(game, {
|
|
255
|
-
width: 140,
|
|
256
|
-
height: 140,
|
|
257
|
-
debug: false,
|
|
258
|
-
debugColor: "#ff00ff"
|
|
259
|
-
});
|
|
260
|
-
this.scene.transform.position(200, -80);
|
|
261
|
-
|
|
262
|
-
// Create overlapping shapes
|
|
263
|
-
this.shapes = [];
|
|
264
|
-
const colors = ["#e94560", "#ffc107", "#00d9ff", "#7bed9f"];
|
|
265
|
-
const positions = [
|
|
266
|
-
{ x: -20, y: -20 },
|
|
267
|
-
{ x: 0, y: -10 },
|
|
268
|
-
{ x: 20, y: 0 },
|
|
269
|
-
{ x: 0, y: 10 }
|
|
270
|
-
];
|
|
271
|
-
|
|
272
|
-
colors.forEach((color, i) => {
|
|
273
|
-
const rect = new Rectangle({
|
|
274
|
-
width: 50,
|
|
275
|
-
height: 50,
|
|
276
|
-
color: color,
|
|
277
|
-
stroke: "#fff",
|
|
278
|
-
lineWidth: 2
|
|
279
|
-
});
|
|
280
|
-
rect.transform.position(positions[i].x, positions[i].y);
|
|
281
|
-
const wrapped = wrapShape(game, rect);
|
|
282
|
-
this.shapes.push(wrapped);
|
|
283
|
-
this.scene.add(wrapped);
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
// Label
|
|
287
|
-
this.label = new TextShape("Z-Ordering", {
|
|
288
|
-
x: 200,
|
|
289
|
-
y: -150,
|
|
290
|
-
font: "bold 12px monospace",
|
|
291
|
-
color: "#fff",
|
|
292
|
-
align: "center"
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
this.elapsed = 0;
|
|
296
|
-
this.lastSwap = 0;
|
|
297
|
-
this.swapInterval = 1.5; // seconds between z-order changes
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
update(dt) {
|
|
301
|
-
super.update(dt);
|
|
302
|
-
this.elapsed += dt;
|
|
303
|
-
|
|
304
|
-
// Periodically bring a different shape to front
|
|
305
|
-
if (this.elapsed - this.lastSwap > this.swapInterval) {
|
|
306
|
-
this.lastSwap = this.elapsed;
|
|
307
|
-
const index = Math.floor(this.elapsed / this.swapInterval) % this.shapes.length;
|
|
308
|
-
this.scene.bringToFront(this.shapes[index]);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// Subtle pulse on the scene
|
|
312
|
-
this.scene.transform.scale(0.95 + Math.sin(this.elapsed * 2) * 0.05);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
draw() {
|
|
316
|
-
super.draw();
|
|
317
|
-
this.scene.render();
|
|
318
|
-
this.label.render();
|
|
319
|
-
}
|
|
320
|
-
}
|