@guinetik/gcanvas 1.0.0 → 1.0.1
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/demos/fluid-simple.html +22 -0
- package/demos/fluid.html +37 -0
- package/demos/index.html +2 -0
- package/demos/js/blob.js +18 -5
- package/demos/js/fluid-simple.js +253 -0
- package/demos/js/fluid.js +527 -0
- package/demos/js/tde/accretiondisk.js +64 -11
- package/demos/js/tde/blackholescene.js +2 -2
- package/demos/js/tde/config.js +2 -2
- package/demos/js/tde/index.js +152 -27
- package/demos/js/tde/lensedstarfield.js +32 -25
- package/demos/js/tde/tdestar.js +78 -98
- package/demos/js/tde/tidalstream.js +23 -7
- package/docs/README.md +230 -222
- package/docs/api/FluidSystem.md +173 -0
- package/docs/concepts/architecture-overview.md +204 -204
- package/docs/concepts/rendering-pipeline.md +279 -279
- package/docs/concepts/two-layer-architecture.md +229 -229
- package/docs/fluid-dynamics.md +97 -0
- package/docs/getting-started/first-game.md +354 -354
- package/docs/getting-started/installation.md +175 -157
- package/docs/modules/collision/README.md +2 -2
- package/docs/modules/fluent/README.md +6 -6
- package/docs/modules/game/README.md +303 -303
- package/docs/modules/isometric-camera.md +2 -2
- package/docs/modules/isometric.md +1 -1
- package/docs/modules/painter/README.md +328 -328
- package/docs/modules/particle/README.md +3 -3
- package/docs/modules/shapes/README.md +221 -221
- package/docs/modules/shapes/base/euclidian.md +123 -123
- package/docs/modules/shapes/base/shape.md +262 -262
- package/docs/modules/shapes/base/transformable.md +243 -243
- package/docs/modules/state/README.md +2 -2
- package/docs/modules/util/README.md +1 -1
- package/docs/modules/util/camera3d.md +3 -3
- package/docs/modules/util/scene3d.md +1 -1
- package/package.json +3 -1
- package/readme.md +19 -5
- package/src/collision/collision.js +75 -0
- package/src/game/index.js +2 -1
- package/src/game/pipeline.js +3 -3
- package/src/game/systems/FluidSystem.js +835 -0
- package/src/game/systems/index.js +11 -0
- package/src/game/ui/button.js +39 -18
- package/src/game/ui/cursor.js +14 -0
- package/src/game/ui/fps.js +12 -4
- package/src/game/ui/index.js +2 -0
- package/src/game/ui/stepper.js +549 -0
- package/src/game/ui/theme.js +121 -0
- package/src/game/ui/togglebutton.js +9 -3
- package/src/game/ui/tooltip.js +11 -4
- package/src/math/fluid.js +507 -0
- package/src/math/index.js +2 -0
- package/src/mixins/anchor.js +17 -7
- package/src/motion/tweenetik.js +16 -0
- package/src/shapes/index.js +1 -0
- package/src/util/camera3d.js +218 -12
- package/types/fluent.d.ts +361 -0
- package/types/game.d.ts +303 -0
- package/types/index.d.ts +144 -5
- package/types/math.d.ts +361 -0
- package/types/motion.d.ts +271 -0
- package/types/particle.d.ts +373 -0
- package/types/shapes.d.ts +107 -9
- package/types/util.d.ts +353 -0
- package/types/webgl.d.ts +109 -0
- package/disk_example.png +0 -0
- package/tde.png +0 -0
|
@@ -1,303 +1,303 @@
|
|
|
1
|
-
# Game Module
|
|
2
|
-
|
|
3
|
-
> Core game loop, Pipeline, GameObjects, and Scenes.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
The game module provides the interactive layer of GCanvas. It manages the game loop, object lifecycle, input handling, and scene organization.
|
|
8
|
-
|
|
9
|
-
## Quick Start
|
|
10
|
-
|
|
11
|
-
```js
|
|
12
|
-
import { Game, Scene, GameObject, Circle } from 'gcanvas';
|
|
13
|
-
|
|
14
|
-
class Player extends GameObject {
|
|
15
|
-
constructor(game) {
|
|
16
|
-
super(game);
|
|
17
|
-
this.shape = new Circle(30, { color: 'blue' });
|
|
18
|
-
this.enableInteractivity(this.shape);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
update(dt) {
|
|
22
|
-
if (this.game.input.isKeyDown('ArrowRight')) {
|
|
23
|
-
this.shape.x += 200 * dt;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
render() {
|
|
28
|
-
this.shape.draw();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
class MyGame extends Game {
|
|
33
|
-
init() {
|
|
34
|
-
super.init();
|
|
35
|
-
this.enableFluidSize();
|
|
36
|
-
|
|
37
|
-
const scene = new Scene(this);
|
|
38
|
-
scene.add(new Player(this));
|
|
39
|
-
this.pipeline.add(scene);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const game = new MyGame(document.getElementById('canvas'));
|
|
44
|
-
game.start();
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Core Classes
|
|
48
|
-
|
|
49
|
-
| Class | Description |
|
|
50
|
-
|-------|-------------|
|
|
51
|
-
| **Game** | Main loop, canvas management, input initialization |
|
|
52
|
-
| **Pipeline** | Manages object collections, update/render dispatch |
|
|
53
|
-
| **GameObject** | Base class for interactive entities |
|
|
54
|
-
| **Scene** | Hierarchical container for GameObjects |
|
|
55
|
-
|
|
56
|
-
## Game Class
|
|
57
|
-
|
|
58
|
-
The entry point for interactive applications.
|
|
59
|
-
|
|
60
|
-
```js
|
|
61
|
-
class MyGame extends Game {
|
|
62
|
-
constructor(canvas) {
|
|
63
|
-
super(canvas);
|
|
64
|
-
this.enableFluidSize(); // Canvas fills viewport
|
|
65
|
-
this.backgroundColor = '#1a1a2e';
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
init() {
|
|
69
|
-
super.init(); // Initialize input systems
|
|
70
|
-
// Create scenes and objects
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
update(dt) {
|
|
74
|
-
super.update(dt); // Update pipeline
|
|
75
|
-
// Custom game logic
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
render() {
|
|
79
|
-
super.render(); // Render pipeline
|
|
80
|
-
// Custom rendering
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const game = new MyGame(canvas);
|
|
85
|
-
game.setFPS(60); // Set target FPS
|
|
86
|
-
game.start(); // Begin game loop
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Key Properties
|
|
90
|
-
|
|
91
|
-
| Property | Type | Description |
|
|
92
|
-
|----------|------|-------------|
|
|
93
|
-
| `canvas` | `HTMLCanvasElement` | The canvas element |
|
|
94
|
-
| `ctx` | `CanvasRenderingContext2D` | 2D context |
|
|
95
|
-
| `pipeline` | `Pipeline` | Object manager |
|
|
96
|
-
| `events` | `EventEmitter` | Event system |
|
|
97
|
-
| `width` | `number` | Canvas width |
|
|
98
|
-
| `height` | `number` | Canvas height |
|
|
99
|
-
| `running` | `boolean` | Is loop running? |
|
|
100
|
-
| `dt` | `number` | Last delta time |
|
|
101
|
-
|
|
102
|
-
### Key Methods
|
|
103
|
-
|
|
104
|
-
| Method | Description |
|
|
105
|
-
|--------|-------------|
|
|
106
|
-
| `start()` | Begin the game loop |
|
|
107
|
-
| `stop()` | Stop the game loop |
|
|
108
|
-
| `init()` | Initialize game (override) |
|
|
109
|
-
| `update(dt)` | Update logic (override) |
|
|
110
|
-
| `render()` | Render logic (override) |
|
|
111
|
-
| `enableFluidSize()` | Auto-resize to window |
|
|
112
|
-
| `setFPS(fps)` | Set target frame rate |
|
|
113
|
-
| `enablePauseOnBlur(bool)` | Pause when tab loses focus |
|
|
114
|
-
|
|
115
|
-
## Pipeline Class
|
|
116
|
-
|
|
117
|
-
Manages collections of objects for update and render.
|
|
118
|
-
|
|
119
|
-
```js
|
|
120
|
-
// Add objects
|
|
121
|
-
game.pipeline.add(scene);
|
|
122
|
-
game.pipeline.add(gameObject);
|
|
123
|
-
|
|
124
|
-
// Remove objects
|
|
125
|
-
game.pipeline.remove(object);
|
|
126
|
-
|
|
127
|
-
// Clear all
|
|
128
|
-
game.pipeline.clear();
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Pipeline automatically:
|
|
132
|
-
- Calls `update(dt)` on active objects
|
|
133
|
-
- Calls `render()` on visible objects
|
|
134
|
-
- Sorts by zIndex
|
|
135
|
-
- Dispatches input events
|
|
136
|
-
|
|
137
|
-
## GameObject Class
|
|
138
|
-
|
|
139
|
-
Base class for all interactive entities.
|
|
140
|
-
|
|
141
|
-
```js
|
|
142
|
-
class Enemy extends GameObject {
|
|
143
|
-
constructor(game) {
|
|
144
|
-
super(game);
|
|
145
|
-
this.shape = new Rectangle({ width: 40, height: 40, color: 'red' });
|
|
146
|
-
this.enableInteractivity(this.shape);
|
|
147
|
-
this.speed = 100;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
update(dt) {
|
|
151
|
-
this.shape.x += this.speed * dt;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
render() {
|
|
155
|
-
this.shape.draw();
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Input events
|
|
159
|
-
onPointerDown(e) { }
|
|
160
|
-
onPointerUp(e) { }
|
|
161
|
-
onPointerMove(e) { }
|
|
162
|
-
onMouseOver() { }
|
|
163
|
-
onMouseOut() { }
|
|
164
|
-
}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### Lifecycle Methods
|
|
168
|
-
|
|
169
|
-
| Method | When Called |
|
|
170
|
-
|--------|-------------|
|
|
171
|
-
| `update(dt)` | Every frame (if active) |
|
|
172
|
-
| `render()` | Every frame (if visible) |
|
|
173
|
-
| `destroy()` | When removed from pipeline |
|
|
174
|
-
|
|
175
|
-
### Input Methods
|
|
176
|
-
|
|
177
|
-
| Method | Event |
|
|
178
|
-
|--------|-------|
|
|
179
|
-
| `onPointerDown(e)` | Click/tap start |
|
|
180
|
-
| `onPointerUp(e)` | Click/tap end |
|
|
181
|
-
| `onPointerMove(e)` | Pointer movement |
|
|
182
|
-
| `onMouseOver()` | Hover enter |
|
|
183
|
-
| `onMouseOut()` | Hover leave |
|
|
184
|
-
|
|
185
|
-
## Scene Class
|
|
186
|
-
|
|
187
|
-
Hierarchical container for GameObjects.
|
|
188
|
-
|
|
189
|
-
```js
|
|
190
|
-
const gameScene = new Scene(game);
|
|
191
|
-
const uiScene = new Scene(game);
|
|
192
|
-
|
|
193
|
-
// Add objects to scenes
|
|
194
|
-
gameScene.add(player);
|
|
195
|
-
gameScene.add(enemy);
|
|
196
|
-
|
|
197
|
-
uiScene.add(healthBar);
|
|
198
|
-
uiScene.add(scoreDisplay);
|
|
199
|
-
|
|
200
|
-
// Add scenes to pipeline (order matters)
|
|
201
|
-
game.pipeline.add(gameScene); // Rendered first
|
|
202
|
-
game.pipeline.add(uiScene); // Rendered on top
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
Scenes provide:
|
|
206
|
-
- Hierarchical organization
|
|
207
|
-
- Coordinate spaces
|
|
208
|
-
- Z-ordering of children
|
|
209
|
-
- Collective transforms
|
|
210
|
-
|
|
211
|
-
## UI Components
|
|
212
|
-
|
|
213
|
-
Built on GameObject and Scene:
|
|
214
|
-
|
|
215
|
-
| Component | Description |
|
|
216
|
-
|-----------|-------------|
|
|
217
|
-
| `Button` | Clickable with visual states |
|
|
218
|
-
| `ToggleButton` | On/off toggle |
|
|
219
|
-
| `Cursor` | Custom cursor |
|
|
220
|
-
| `FPSCounter` | FPS display |
|
|
221
|
-
|
|
222
|
-
```js
|
|
223
|
-
import { Button, FPSCounter } from 'gcanvas';
|
|
224
|
-
|
|
225
|
-
const button = new Button(game, 'Click Me', {
|
|
226
|
-
x: 400,
|
|
227
|
-
y: 300
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
button.on('click', () => {
|
|
231
|
-
console.log('Clicked!');
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
scene.add(button);
|
|
235
|
-
scene.add(new FPSCounter(game, { anchor: 'bottom-right' }));
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
## Input Access
|
|
239
|
-
|
|
240
|
-
```js
|
|
241
|
-
// In GameObject or Game
|
|
242
|
-
update(dt) {
|
|
243
|
-
// Keyboard
|
|
244
|
-
if (this.game.input.isKeyDown('ArrowLeft')) { }
|
|
245
|
-
if (this.game.input.isKeyDown('Space')) { }
|
|
246
|
-
if (this.game.input.isKeyDown('KeyW')) { }
|
|
247
|
-
|
|
248
|
-
// Mouse position
|
|
249
|
-
const mx = this.game.mouse.x;
|
|
250
|
-
const my = this.game.mouse.y;
|
|
251
|
-
}
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
## Events
|
|
255
|
-
|
|
256
|
-
```js
|
|
257
|
-
// Custom events
|
|
258
|
-
game.events.on('player-died', (data) => {
|
|
259
|
-
console.log('Player died:', data);
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
game.events.emit('player-died', { score: 100 });
|
|
263
|
-
|
|
264
|
-
// Remove listener
|
|
265
|
-
game.events.off('player-died', handler);
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
## Architecture Diagram
|
|
269
|
-
|
|
270
|
-
```
|
|
271
|
-
┌─────────────────────────────────────────────────────────┐
|
|
272
|
-
│ Game │
|
|
273
|
-
│ ┌────────────────────────────────────────────────────┐ │
|
|
274
|
-
│ │ Pipeline │ │
|
|
275
|
-
│ │ ┌──────────────────────────────────────────────┐ │ │
|
|
276
|
-
│ │ │ Scene │ │ │
|
|
277
|
-
│ │ │ ┌────────────┐ ┌────────────┐ │ │ │
|
|
278
|
-
│ │ │ │ GameObject │ │ GameObject │ ... │ │ │
|
|
279
|
-
│ │ │ │ + Shape │ │ + Shape │ │ │ │
|
|
280
|
-
│ │ │ └────────────┘ └────────────┘ │ │ │
|
|
281
|
-
│ │ └──────────────────────────────────────────────┘ │ │
|
|
282
|
-
│ └────────────────────────────────────────────────────┘ │
|
|
283
|
-
│ │ │
|
|
284
|
-
│ ▼ │
|
|
285
|
-
│ ┌────────────┐ │
|
|
286
|
-
│ │ Game Loop │ │
|
|
287
|
-
│ │ update(dt) │ │
|
|
288
|
-
│ │ render() │ │
|
|
289
|
-
│ └────────────┘ │
|
|
290
|
-
└─────────────────────────────────────────────────────────┘
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
## Related
|
|
294
|
-
|
|
295
|
-
- [Game Lifecycle](../../concepts/lifecycle.md) - Update/render cycle
|
|
296
|
-
- [Two-Layer Architecture](../../concepts/two-layer-architecture.md) - Shape vs Game layer
|
|
297
|
-
- [First Game Guide](../../getting-started/first-game.md)
|
|
298
|
-
|
|
299
|
-
## See Also
|
|
300
|
-
|
|
301
|
-
- [Shapes Module](../shapes/README.md)
|
|
302
|
-
- [IO Module](../io/README.md) - Input handling
|
|
303
|
-
- [Motion Module](../motion/README.md) - Animation
|
|
1
|
+
# Game Module
|
|
2
|
+
|
|
3
|
+
> Core game loop, Pipeline, GameObjects, and Scenes.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The game module provides the interactive layer of GCanvas. It manages the game loop, object lifecycle, input handling, and scene organization.
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import { Game, Scene, GameObject, Circle } from '@guinetik/gcanvas';
|
|
13
|
+
|
|
14
|
+
class Player extends GameObject {
|
|
15
|
+
constructor(game) {
|
|
16
|
+
super(game);
|
|
17
|
+
this.shape = new Circle(30, { color: 'blue' });
|
|
18
|
+
this.enableInteractivity(this.shape);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
update(dt) {
|
|
22
|
+
if (this.game.input.isKeyDown('ArrowRight')) {
|
|
23
|
+
this.shape.x += 200 * dt;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
render() {
|
|
28
|
+
this.shape.draw();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
class MyGame extends Game {
|
|
33
|
+
init() {
|
|
34
|
+
super.init();
|
|
35
|
+
this.enableFluidSize();
|
|
36
|
+
|
|
37
|
+
const scene = new Scene(this);
|
|
38
|
+
scene.add(new Player(this));
|
|
39
|
+
this.pipeline.add(scene);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const game = new MyGame(document.getElementById('canvas'));
|
|
44
|
+
game.start();
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Core Classes
|
|
48
|
+
|
|
49
|
+
| Class | Description |
|
|
50
|
+
|-------|-------------|
|
|
51
|
+
| **Game** | Main loop, canvas management, input initialization |
|
|
52
|
+
| **Pipeline** | Manages object collections, update/render dispatch |
|
|
53
|
+
| **GameObject** | Base class for interactive entities |
|
|
54
|
+
| **Scene** | Hierarchical container for GameObjects |
|
|
55
|
+
|
|
56
|
+
## Game Class
|
|
57
|
+
|
|
58
|
+
The entry point for interactive applications.
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
class MyGame extends Game {
|
|
62
|
+
constructor(canvas) {
|
|
63
|
+
super(canvas);
|
|
64
|
+
this.enableFluidSize(); // Canvas fills viewport
|
|
65
|
+
this.backgroundColor = '#1a1a2e';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
init() {
|
|
69
|
+
super.init(); // Initialize input systems
|
|
70
|
+
// Create scenes and objects
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
update(dt) {
|
|
74
|
+
super.update(dt); // Update pipeline
|
|
75
|
+
// Custom game logic
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
render() {
|
|
79
|
+
super.render(); // Render pipeline
|
|
80
|
+
// Custom rendering
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const game = new MyGame(canvas);
|
|
85
|
+
game.setFPS(60); // Set target FPS
|
|
86
|
+
game.start(); // Begin game loop
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Key Properties
|
|
90
|
+
|
|
91
|
+
| Property | Type | Description |
|
|
92
|
+
|----------|------|-------------|
|
|
93
|
+
| `canvas` | `HTMLCanvasElement` | The canvas element |
|
|
94
|
+
| `ctx` | `CanvasRenderingContext2D` | 2D context |
|
|
95
|
+
| `pipeline` | `Pipeline` | Object manager |
|
|
96
|
+
| `events` | `EventEmitter` | Event system |
|
|
97
|
+
| `width` | `number` | Canvas width |
|
|
98
|
+
| `height` | `number` | Canvas height |
|
|
99
|
+
| `running` | `boolean` | Is loop running? |
|
|
100
|
+
| `dt` | `number` | Last delta time |
|
|
101
|
+
|
|
102
|
+
### Key Methods
|
|
103
|
+
|
|
104
|
+
| Method | Description |
|
|
105
|
+
|--------|-------------|
|
|
106
|
+
| `start()` | Begin the game loop |
|
|
107
|
+
| `stop()` | Stop the game loop |
|
|
108
|
+
| `init()` | Initialize game (override) |
|
|
109
|
+
| `update(dt)` | Update logic (override) |
|
|
110
|
+
| `render()` | Render logic (override) |
|
|
111
|
+
| `enableFluidSize()` | Auto-resize to window |
|
|
112
|
+
| `setFPS(fps)` | Set target frame rate |
|
|
113
|
+
| `enablePauseOnBlur(bool)` | Pause when tab loses focus |
|
|
114
|
+
|
|
115
|
+
## Pipeline Class
|
|
116
|
+
|
|
117
|
+
Manages collections of objects for update and render.
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
// Add objects
|
|
121
|
+
game.pipeline.add(scene);
|
|
122
|
+
game.pipeline.add(gameObject);
|
|
123
|
+
|
|
124
|
+
// Remove objects
|
|
125
|
+
game.pipeline.remove(object);
|
|
126
|
+
|
|
127
|
+
// Clear all
|
|
128
|
+
game.pipeline.clear();
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Pipeline automatically:
|
|
132
|
+
- Calls `update(dt)` on active objects
|
|
133
|
+
- Calls `render()` on visible objects
|
|
134
|
+
- Sorts by zIndex
|
|
135
|
+
- Dispatches input events
|
|
136
|
+
|
|
137
|
+
## GameObject Class
|
|
138
|
+
|
|
139
|
+
Base class for all interactive entities.
|
|
140
|
+
|
|
141
|
+
```js
|
|
142
|
+
class Enemy extends GameObject {
|
|
143
|
+
constructor(game) {
|
|
144
|
+
super(game);
|
|
145
|
+
this.shape = new Rectangle({ width: 40, height: 40, color: 'red' });
|
|
146
|
+
this.enableInteractivity(this.shape);
|
|
147
|
+
this.speed = 100;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
update(dt) {
|
|
151
|
+
this.shape.x += this.speed * dt;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
render() {
|
|
155
|
+
this.shape.draw();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Input events
|
|
159
|
+
onPointerDown(e) { }
|
|
160
|
+
onPointerUp(e) { }
|
|
161
|
+
onPointerMove(e) { }
|
|
162
|
+
onMouseOver() { }
|
|
163
|
+
onMouseOut() { }
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Lifecycle Methods
|
|
168
|
+
|
|
169
|
+
| Method | When Called |
|
|
170
|
+
|--------|-------------|
|
|
171
|
+
| `update(dt)` | Every frame (if active) |
|
|
172
|
+
| `render()` | Every frame (if visible) |
|
|
173
|
+
| `destroy()` | When removed from pipeline |
|
|
174
|
+
|
|
175
|
+
### Input Methods
|
|
176
|
+
|
|
177
|
+
| Method | Event |
|
|
178
|
+
|--------|-------|
|
|
179
|
+
| `onPointerDown(e)` | Click/tap start |
|
|
180
|
+
| `onPointerUp(e)` | Click/tap end |
|
|
181
|
+
| `onPointerMove(e)` | Pointer movement |
|
|
182
|
+
| `onMouseOver()` | Hover enter |
|
|
183
|
+
| `onMouseOut()` | Hover leave |
|
|
184
|
+
|
|
185
|
+
## Scene Class
|
|
186
|
+
|
|
187
|
+
Hierarchical container for GameObjects.
|
|
188
|
+
|
|
189
|
+
```js
|
|
190
|
+
const gameScene = new Scene(game);
|
|
191
|
+
const uiScene = new Scene(game);
|
|
192
|
+
|
|
193
|
+
// Add objects to scenes
|
|
194
|
+
gameScene.add(player);
|
|
195
|
+
gameScene.add(enemy);
|
|
196
|
+
|
|
197
|
+
uiScene.add(healthBar);
|
|
198
|
+
uiScene.add(scoreDisplay);
|
|
199
|
+
|
|
200
|
+
// Add scenes to pipeline (order matters)
|
|
201
|
+
game.pipeline.add(gameScene); // Rendered first
|
|
202
|
+
game.pipeline.add(uiScene); // Rendered on top
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Scenes provide:
|
|
206
|
+
- Hierarchical organization
|
|
207
|
+
- Coordinate spaces
|
|
208
|
+
- Z-ordering of children
|
|
209
|
+
- Collective transforms
|
|
210
|
+
|
|
211
|
+
## UI Components
|
|
212
|
+
|
|
213
|
+
Built on GameObject and Scene:
|
|
214
|
+
|
|
215
|
+
| Component | Description |
|
|
216
|
+
|-----------|-------------|
|
|
217
|
+
| `Button` | Clickable with visual states |
|
|
218
|
+
| `ToggleButton` | On/off toggle |
|
|
219
|
+
| `Cursor` | Custom cursor |
|
|
220
|
+
| `FPSCounter` | FPS display |
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
import { Button, FPSCounter } from '@guinetik/gcanvas';
|
|
224
|
+
|
|
225
|
+
const button = new Button(game, 'Click Me', {
|
|
226
|
+
x: 400,
|
|
227
|
+
y: 300
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
button.on('click', () => {
|
|
231
|
+
console.log('Clicked!');
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
scene.add(button);
|
|
235
|
+
scene.add(new FPSCounter(game, { anchor: 'bottom-right' }));
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Input Access
|
|
239
|
+
|
|
240
|
+
```js
|
|
241
|
+
// In GameObject or Game
|
|
242
|
+
update(dt) {
|
|
243
|
+
// Keyboard
|
|
244
|
+
if (this.game.input.isKeyDown('ArrowLeft')) { }
|
|
245
|
+
if (this.game.input.isKeyDown('Space')) { }
|
|
246
|
+
if (this.game.input.isKeyDown('KeyW')) { }
|
|
247
|
+
|
|
248
|
+
// Mouse position
|
|
249
|
+
const mx = this.game.mouse.x;
|
|
250
|
+
const my = this.game.mouse.y;
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Events
|
|
255
|
+
|
|
256
|
+
```js
|
|
257
|
+
// Custom events
|
|
258
|
+
game.events.on('player-died', (data) => {
|
|
259
|
+
console.log('Player died:', data);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
game.events.emit('player-died', { score: 100 });
|
|
263
|
+
|
|
264
|
+
// Remove listener
|
|
265
|
+
game.events.off('player-died', handler);
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Architecture Diagram
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
┌─────────────────────────────────────────────────────────┐
|
|
272
|
+
│ Game │
|
|
273
|
+
│ ┌────────────────────────────────────────────────────┐ │
|
|
274
|
+
│ │ Pipeline │ │
|
|
275
|
+
│ │ ┌──────────────────────────────────────────────┐ │ │
|
|
276
|
+
│ │ │ Scene │ │ │
|
|
277
|
+
│ │ │ ┌────────────┐ ┌────────────┐ │ │ │
|
|
278
|
+
│ │ │ │ GameObject │ │ GameObject │ ... │ │ │
|
|
279
|
+
│ │ │ │ + Shape │ │ + Shape │ │ │ │
|
|
280
|
+
│ │ │ └────────────┘ └────────────┘ │ │ │
|
|
281
|
+
│ │ └──────────────────────────────────────────────┘ │ │
|
|
282
|
+
│ └────────────────────────────────────────────────────┘ │
|
|
283
|
+
│ │ │
|
|
284
|
+
│ ▼ │
|
|
285
|
+
│ ┌────────────┐ │
|
|
286
|
+
│ │ Game Loop │ │
|
|
287
|
+
│ │ update(dt) │ │
|
|
288
|
+
│ │ render() │ │
|
|
289
|
+
│ └────────────┘ │
|
|
290
|
+
└─────────────────────────────────────────────────────────┘
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Related
|
|
294
|
+
|
|
295
|
+
- [Game Lifecycle](../../concepts/lifecycle.md) - Update/render cycle
|
|
296
|
+
- [Two-Layer Architecture](../../concepts/two-layer-architecture.md) - Shape vs Game layer
|
|
297
|
+
- [First Game Guide](../../getting-started/first-game.md)
|
|
298
|
+
|
|
299
|
+
## See Also
|
|
300
|
+
|
|
301
|
+
- [Shapes Module](../shapes/README.md)
|
|
302
|
+
- [IO Module](../io/README.md) - Input handling
|
|
303
|
+
- [Motion Module](../motion/README.md) - Animation
|
|
@@ -15,7 +15,7 @@ Unlike `Camera3D` which provides free 3D rotation, `IsometricCamera` is designed
|
|
|
15
15
|
## Basic Usage
|
|
16
16
|
|
|
17
17
|
```javascript
|
|
18
|
-
import { IsometricCamera, IsometricScene } from 'gcanvas';
|
|
18
|
+
import { IsometricCamera, IsometricScene } from '@guinetik/gcanvas';
|
|
19
19
|
|
|
20
20
|
// Create camera with 90° rotation steps (recommended for isometric)
|
|
21
21
|
const camera = new IsometricCamera({
|
|
@@ -168,7 +168,7 @@ isoY = (rotatedX + rotatedY) * (tileHeight / 2)
|
|
|
168
168
|
Add rotation buttons to your game:
|
|
169
169
|
|
|
170
170
|
```javascript
|
|
171
|
-
import { Button, Keys } from 'gcanvas';
|
|
171
|
+
import { Button, Keys } from '@guinetik/gcanvas';
|
|
172
172
|
|
|
173
173
|
// Arrow buttons
|
|
174
174
|
const leftBtn = new Button(game, {
|