nexus-2d 0.0.1 → 0.0.2

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.
@@ -0,0 +1,131 @@
1
+ /**
2
+ * ParticleEmitter - manages pool of particles
3
+ *
4
+ * Common use cases:
5
+ * - Explosion (burst of particles)
6
+ * - Smoke trail (continuous emission)
7
+ * - Coin sparkle (short burst)
8
+ * - Dust cloud (ground impact)
9
+ * - Magic effect (custom colors/behavior)
10
+ */
11
+ export class ParticleEmitter extends Node {
12
+ constructor(name: any, options?: {});
13
+ maxParticles: any;
14
+ particles: {
15
+ active: boolean;
16
+ x: number;
17
+ y: number;
18
+ vx: number;
19
+ vy: number;
20
+ life: number;
21
+ maxLife: number;
22
+ size: number;
23
+ startSize: number;
24
+ endSize: number;
25
+ r: number;
26
+ g: number;
27
+ b: number;
28
+ a: number;
29
+ startR: number;
30
+ startG: number;
31
+ startB: number;
32
+ startA: number;
33
+ endR: number;
34
+ endG: number;
35
+ endB: number;
36
+ endA: number;
37
+ }[];
38
+ activeCount: number;
39
+ emitting: boolean;
40
+ emissionRate: any;
41
+ emissionTimer: number;
42
+ lifetime: any;
43
+ speed: any;
44
+ angle: any;
45
+ spread: any;
46
+ gravity: any;
47
+ drag: any;
48
+ startSize: any;
49
+ endSize: any;
50
+ startColor: any;
51
+ endColor: any;
52
+ emitterShape: any;
53
+ emitterSize: any;
54
+ /**
55
+ *
56
+ * @param {Array<number, number>} value
57
+ * @returns {number}
58
+ */
59
+ randomValue(value: Array<number, number>): number;
60
+ spawnParticle(x: any, y: any, vx: any, vy: any): {
61
+ active: boolean;
62
+ x: number;
63
+ y: number;
64
+ vx: number;
65
+ vy: number;
66
+ life: number;
67
+ maxLife: number;
68
+ size: number;
69
+ startSize: number;
70
+ endSize: number;
71
+ r: number;
72
+ g: number;
73
+ b: number;
74
+ a: number;
75
+ startR: number;
76
+ startG: number;
77
+ startB: number;
78
+ startA: number;
79
+ endR: number;
80
+ endG: number;
81
+ endB: number;
82
+ endA: number;
83
+ };
84
+ burst(count: any): void;
85
+ startEmitting(): void;
86
+ stopEmitting(): void;
87
+ clear(): void;
88
+ getActiveCount(): number;
89
+ hasActiveParticles(): boolean;
90
+ }
91
+ export class ParticlePresets {
92
+ /**
93
+ * burst of orange/red particles
94
+ * @param {*} x
95
+ * @param {*} y
96
+ * @param {*} options
97
+ * @returns
98
+ */
99
+ static explosion(x: any, y: any, options?: any): ParticleEmitter;
100
+ /**
101
+ * continuous upward-floating particles
102
+ * @param {*} x
103
+ * @param {*} y
104
+ * @param {*} options
105
+ * @returns
106
+ */
107
+ static smoke(x: any, y: any, options?: any): ParticleEmitter;
108
+ /**
109
+ *
110
+ * @param {*} x
111
+ * @param {*} y
112
+ * @param {*} options
113
+ * @returns
114
+ */
115
+ static sparkles(x: any, y: any, options?: any): ParticleEmitter;
116
+ /**
117
+ * impact clouds
118
+ * @param {*} x
119
+ * @param {*} y
120
+ * @param {*} options
121
+ * @returns
122
+ */
123
+ static dustCloud(x: any, y: any, options?: any): ParticleEmitter;
124
+ static blood(x: any, y: any, directionX?: number, directionY?: number, options?: {}): ParticleEmitter;
125
+ static trail(color?: {
126
+ r: number;
127
+ g: number;
128
+ b: number;
129
+ }, options?: {}): ParticleEmitter;
130
+ }
131
+ import { Node } from "./core.js";
@@ -0,0 +1,294 @@
1
+ /**
2
+ * PhysicsWorld - singleton that manages Matter.js engine
3
+ *
4
+ * Why singleton:
5
+ * - Only one physics simulation per game
6
+ * - Global gravity, timestep settings
7
+ * - Central collision event dispatcher
8
+ *
9
+ * Common use case: platformer needs gravity, space game doesn't
10
+ */
11
+ export class PhysicsWorld {
12
+ constructor(options?: {});
13
+ engine: any;
14
+ world: any;
15
+ gravity: any;
16
+ timeScale: number;
17
+ fixedDelta: any;
18
+ accumulator: number;
19
+ maxSubSteps: any;
20
+ bodies: Map<any, any>;
21
+ /**
22
+ * Setup Matter.js collision callbacks
23
+ *
24
+ * Matter fires events: collisionStart, collisionActive, collisionEnd
25
+ * We translate these to our node callbacks
26
+ */
27
+ setupCollisionEvents(): void;
28
+ /**
29
+ * Step physics with fixed timestep
30
+ *
31
+ * Why fixed timestep:
32
+ * - Game runs at variable FPS (30-144fps)
33
+ * - Physics needs consistent delta (16.66ms for 60fps)
34
+ * - Accumulate real delta, consume in fixed chunks
35
+ *
36
+ * Example: Frame takes 33ms (30fps)
37
+ * - accumulator += 0.033
38
+ * - Step 1: 0.033 - 0.0166 = 0.0166 remaining
39
+ * - Step 2: 0.0166 - 0.0166 = 0 remaining
40
+ * - Result: physics stepped twice, stays stable
41
+ */
42
+ step(delta: any): void;
43
+ /**
44
+ * Add body to world
45
+ */
46
+ addBody(matterBody: any, rigidBodyNode: any): void;
47
+ /**
48
+ * Remove body from world
49
+ */
50
+ removeBody(matterBody: any): void;
51
+ /**
52
+ * Query physics world (useful for raycasts, area queries)
53
+ */
54
+ queryPoint(x: any, y: any): any;
55
+ queryRegion(bounds: any): any;
56
+ }
57
+ /**
58
+ * RigidBody2D - node that syncs with Matter.js body
59
+ *
60
+ * Body types:
61
+ * - dynamic: Physics controls it (gravity, forces apply)
62
+ * - kinematic: You control it, physics detects collisions
63
+ * - static: Never moves (walls, floors)
64
+ *
65
+ * Authority rules:
66
+ * - Dynamic: Physics -> Scene graph (read Matter position)
67
+ * - Kinematic: Scene graph -> Physics (write to Matter position)
68
+ * - Static: Set once, never sync
69
+ */
70
+ export class RigidBody2D extends Node {
71
+ /**
72
+ * Creates an instance of the physics object.
73
+ *
74
+ * @param {string} name - The name of the physics object.
75
+ * @param {Object} [options={}] - The options for the physics object.
76
+ * @param {string} [options.type='dynamic'] - The type of the physics object (dynamic, kinematic, static).
77
+ * @param {number} [options.mass=1.0] - The mass of the physics object.
78
+ * @param {number} [options.friction=0.1] - The friction coefficient of the physics object.
79
+ * @param {number} [options.restitution=0.0] - The bounciness of the physics object.
80
+ * @param {number} [options.linearDamping=0.01] - The linear damping (air resistance) of the physics object.
81
+ * @param {number} [options.angularDamping=0.01] - The angular damping of the physics object.
82
+ * @param {number} [options.collisionLayer=0x0001] - The collision layer of the physics object.
83
+ * @param {number} [options.collisionMask=0xFFFF] - The collision mask of the physics object, which determines what it can collide with.
84
+ */
85
+ constructor(name: string, options?: {
86
+ type?: string;
87
+ mass?: number;
88
+ friction?: number;
89
+ restitution?: number;
90
+ linearDamping?: number;
91
+ angularDamping?: number;
92
+ collisionLayer?: number;
93
+ collisionMask?: number;
94
+ });
95
+ type: string;
96
+ mass: number;
97
+ friction: number;
98
+ restitution: number;
99
+ linearDamping: number;
100
+ angularDamping: number;
101
+ pivot: any;
102
+ sprite: any;
103
+ body: any;
104
+ onCollisionEnter: any;
105
+ onCollisionStay: any;
106
+ onCollisionExit: any;
107
+ collisionLayer: number;
108
+ collisionMask: number;
109
+ anchorOffset: {
110
+ x: number;
111
+ y: any;
112
+ } | {
113
+ x: any;
114
+ y: number;
115
+ };
116
+ /**
117
+ * Add collision box with automatic anchor matching pivot
118
+ *
119
+ * Common use: player.addCollisionBox(24, 40)
120
+ * → Creates box anchored at body's pivot point
121
+ *
122
+ * @param {number} width - Box width
123
+ * @param {number} height - Box height
124
+ * @param {Object} options - Additional options (friction, etc.)
125
+ */
126
+ addCollisionBox(width: number, height: number, options?: any): CollisionShape2D;
127
+ /**
128
+ * Add collision circle with automatic anchor matching pivot
129
+ */
130
+ addCollisionCircle(radius: any, options?: {}): CollisionShape2D;
131
+ /**
132
+ * Set sprite and auto-configure offset to match pivot
133
+ *
134
+ * This is the magic: sprite offset calculated from pivot + sprite size
135
+ *
136
+ * @param {Sprite} sprite - Sprite instance to attach
137
+ */
138
+ setSprite(sprite: Sprite): void;
139
+ /**
140
+ * Calculate sprite offset from pivot point
141
+ *
142
+ * The sprite's offset determines where its top-left corner
143
+ * is drawn relative to the parent position.
144
+ *
145
+ * Example: pivot = 'bottom-center', sprite = 16x40
146
+ * - We want sprite bottom-center at parent position
147
+ * - Sprite draws from top-left
148
+ * - So offset = (-8, -40) to shift it into place
149
+ */
150
+ updateSpriteOffset(): void;
151
+ /**
152
+ * Get offset from pivot point to top-left corner
153
+ *
154
+ * This converts our pivot-based system to sprite's top-left based system
155
+ *
156
+ * @param {number} width - Sprite/shape width
157
+ * @param {number} height - Sprite/shape height
158
+ * @returns {{x: number, y: number}} - Offset to top-left
159
+ */
160
+ getPivotToTopLeftOffset(width: number, height: number): {
161
+ x: number;
162
+ y: number;
163
+ };
164
+ /**
165
+ * Create Matter.js body from collision shapes
166
+ *
167
+ * This is called when first CollisionShape2D child is added
168
+ */
169
+ createBody(): void;
170
+ /**
171
+ * Apply force (for dynamic bodies)
172
+ */
173
+ applyForce(forceX: any, forceY: any, worldX?: any, worldY?: any): void;
174
+ /**
175
+ * Set velocity directly (impulse)
176
+ */
177
+ setVelocity(vx: any, vy: any): void;
178
+ getVelocity(): {
179
+ x: any;
180
+ y: any;
181
+ };
182
+ /**
183
+ * Cleanup when removed from scene
184
+ */
185
+ destroy(): void;
186
+ }
187
+ /**
188
+ * CollisionShape2D - defines physical shape for RigidBody2D
189
+ *
190
+ * Why separate from RigidBody2D:
191
+ * - One body can have multiple shapes (compound collision)
192
+ * - Shapes can be offset from body center
193
+ * - Easier to visualize/debug
194
+ *
195
+ * Shape types: box, circle, polygon
196
+ */
197
+ export class CollisionShape2D extends Node {
198
+ constructor(shapeType: any, options?: {});
199
+ shapeType: any;
200
+ options: {};
201
+ anchor: any;
202
+ anchorOffset: {
203
+ x: number;
204
+ y: any;
205
+ } | {
206
+ x: any;
207
+ y: number;
208
+ };
209
+ /**
210
+ * Calculate offset from anchor point to geometric center
211
+ *
212
+ * This tells Matter.js where to position the body center
213
+ * so the anchor point ends up at the parent position
214
+ */
215
+ calculateAnchorOffset(): {
216
+ x: number;
217
+ y: any;
218
+ } | {
219
+ x: any;
220
+ y: number;
221
+ };
222
+ /**
223
+ * Get anchor offset for box shapes
224
+ *
225
+ * @param {number} width - Box width
226
+ * @param {number} height - Box height
227
+ * @returns {{x: number, y: number}} - Offset from anchor to center
228
+ */
229
+ getBoxAnchorOffset(width: number, height: number): {
230
+ x: number;
231
+ y: number;
232
+ };
233
+ /**
234
+ * Get anchor offset for circle shapes
235
+ *
236
+ * Circles support: center, top, bottom, left, right
237
+ * (diagonal anchors don't make much sense for circles)
238
+ */
239
+ getCircleAnchorOffset(radius: any): {
240
+ x: number;
241
+ y: any;
242
+ } | {
243
+ x: any;
244
+ y: number;
245
+ };
246
+ /**
247
+ * Create Matter.js body with anchor offset applied
248
+ *
249
+ * Key change: Add anchorOffset to position so Matter's center
250
+ * ends up correctly relative to parent's anchor point
251
+ */
252
+ createMatterBody(): any;
253
+ }
254
+ /**
255
+ * Utility: Create common physics bodies quickly
256
+ */
257
+ export class PhysicsFactory {
258
+ /**
259
+ * Create box body with anchor support
260
+ *
261
+ * @param {string} name - Body name
262
+ * @param {number} x - X position (at anchor point)
263
+ * @param {number} y - Y position (at anchor point)
264
+ * @param {number} width - Box width
265
+ * @param {number} height - Box height
266
+ * @param {string} type - 'dynamic', 'kinematic', 'static'
267
+ * @param {string} anchor - Anchor point (default: 'center')
268
+ */
269
+ static createBox(name: string, x: number, y: number, width: number, height: number, type?: string, anchor?: string): RigidBody2D;
270
+ /**
271
+ * Create circle body with anchor support
272
+ */
273
+ static createCircle(name: any, x: any, y: any, radius: any, type?: string, anchor?: string): RigidBody2D;
274
+ /**
275
+ * Create static ground with bottom-center anchor
276
+ *
277
+ * Common use: Tilemap collision bodies
278
+ * The (x, y) you pass is the top-center of the ground surface
279
+ */
280
+ static createGround(name: any, x: any, y: any, width: any, height: any): RigidBody2D;
281
+ /**
282
+ * Create platformer character body
283
+ *
284
+ * Common pattern: Collision box bottom-center at feet position
285
+ *
286
+ * @param {string} name - Character name
287
+ * @param {number} x - X position (feet X)
288
+ * @param {number} y - Y position (feet Y - ground level)
289
+ * @param {number} width - Collision width
290
+ * @param {number} height - Collision height
291
+ */
292
+ static createPlatformerCharacter(name: string, x: number, y: number, width: number, height: number): RigidBody2D;
293
+ }
294
+ import { Node } from './core.js';
@@ -0,0 +1,154 @@
1
+ export function createPhysicsWorld(canvas: any, options?: {}): PhysicsWorld;
2
+ export class RigidBody2D extends Node {
3
+ constructor(name: any, options?: {});
4
+ type: any;
5
+ mass: any;
6
+ friction: any;
7
+ restitution: any;
8
+ linearDamping: any;
9
+ angularDamping: any;
10
+ fixedRotation: any;
11
+ pivot: any;
12
+ gravityScale: any;
13
+ body: any;
14
+ onCollisionEnter: any;
15
+ onCollisionStay: any;
16
+ onCollisionExit: any;
17
+ collisionCategory: any;
18
+ collisionMask: any;
19
+ anchorOffset: any;
20
+ sprite: any;
21
+ /**
22
+ * Add collision box with automatic anchor matching
23
+ *
24
+ * @param {number} widthPixels - Box width in pixels
25
+ * @param {number} heightPixels - Box height in pixels
26
+ */
27
+ addCollisionBox(widthPixels: number, heightPixels: number, options?: {}): CollisionShape2D;
28
+ /**
29
+ * Add collision circle
30
+ */
31
+ addCollisionCircle(radiusPixels: any, options?: {}): CollisionShape2D;
32
+ addCollisionShape(shape: any): any;
33
+ addCollisionPolygon(points?: any[], options?: {}): CollisionShape2D;
34
+ addCollisionPolyline(points?: any[], options?: {}): CollisionShape2D;
35
+ addCollisionPoint(options?: {}): CollisionShape2D;
36
+ addCollisionFromParsed(parsed: any, options?: {}): CollisionShape2D;
37
+ /**
38
+ * Set sprite and auto-configure offset
39
+ */
40
+ setSprite(sprite: any): void;
41
+ updateSpriteOffset(): void;
42
+ getPivotToTopLeftOffset(width: any, height: any): {
43
+ x: number;
44
+ y: number;
45
+ };
46
+ createBody(): void;
47
+ /**
48
+ * Apply force (for dynamic bodies)
49
+ * Forces are in SCREEN space (pixels/s²), converted internally
50
+ */
51
+ applyForce(forceXPixels: any, forceYPixels: any, worldXPixels?: any, worldYPixels?: any): void;
52
+ /**
53
+ * Apply impulse (instant velocity change)
54
+ * Impulses are in SCREEN space (pixels/s), converted internally
55
+ */
56
+ applyImpulse(impulseXPixels: any, impulseYPixels: any, worldXPixels?: any, worldYPixels?: any): void;
57
+ /**
58
+ * Set velocity directly (in screen space: pixels/s)
59
+ */
60
+ setVelocity(vxPixels: any, vyPixels: any): void;
61
+ /**
62
+ * Get velocity (in screen space: pixels/s)
63
+ */
64
+ getVelocity(): any;
65
+ /**
66
+ * Cleanup
67
+ */
68
+ destroy(): void;
69
+ }
70
+ export class CollisionShape2D extends Node {
71
+ constructor(shapeType: any, options?: {});
72
+ shapeType: any;
73
+ options: {};
74
+ anchor: any;
75
+ anchorOffset: {
76
+ x: number;
77
+ y: any;
78
+ } | {
79
+ x: any;
80
+ y: number;
81
+ };
82
+ calculateAnchorOffset(): {
83
+ x: number;
84
+ y: any;
85
+ } | {
86
+ x: any;
87
+ y: number;
88
+ };
89
+ getBoxAnchorOffset(width: any, height: any): {
90
+ x: number;
91
+ y: number;
92
+ };
93
+ getCircleAnchorOffset(radius: any): {
94
+ x: number;
95
+ y: any;
96
+ } | {
97
+ x: any;
98
+ y: number;
99
+ };
100
+ isConvex(points: any): boolean;
101
+ toPlanckVertices(points: any, physicsWorld: any): Vec2[];
102
+ releaseVecs(vecs: any): void;
103
+ createPlanckFixture(body: any, physicsWorld: any): any;
104
+ }
105
+ export class PhysicsFactory {
106
+ static createBox(name: any, xPixels: any, yPixels: any, widthPixels: any, heightPixels: any, type?: string, anchor?: string): RigidBody2D;
107
+ static createCircle(name: any, xPixels: any, yPixels: any, radiusPixels: any, type?: string, anchor?: string): RigidBody2D;
108
+ static createGround(name: any, xPixels: any, yPixels: any, widthPixels: any, heightPixels: any): RigidBody2D;
109
+ static createPlatformerCharacter(name: any, xPixels: any, yPixels: any, widthPixels: any, heightPixels: any): RigidBody2D;
110
+ static createPolygon(name: any, baseX: any, baseY: any, points?: any[], type?: string, anchor?: string, closed?: boolean, shapeOptions?: {}): RigidBody2D;
111
+ static createPolyline(name: any, baseX: any, baseY: any, points?: any[], type?: string, anchor?: string, shapeOptions?: {}): RigidBody2D;
112
+ static createFromParsedShape(parsed: any, name: any, bodyType?: string, options?: {}): RigidBody2D;
113
+ }
114
+ declare class PhysicsWorld {
115
+ constructor(options?: {});
116
+ worldWidthPixels: any;
117
+ worldHeightPixels: any;
118
+ ppm: any;
119
+ worldWidthMeters: number;
120
+ worldHeightMeters: number;
121
+ world: World;
122
+ fixedDelta: any;
123
+ accumulator: number;
124
+ maxSubSteps: any;
125
+ bodies: Map<any, any>;
126
+ pixelsToMeters(pixels: any): number;
127
+ metersToPixels(meters: any): number;
128
+ screenToWorld(screenX: any, screenY: any): {
129
+ x: number;
130
+ y: number;
131
+ };
132
+ worldToScreen(worldX: any, worldY: any): {
133
+ x: number;
134
+ y: number;
135
+ };
136
+ screenVelToWorld(vxPixels: any, vyPixels: any): {
137
+ x: number;
138
+ y: number;
139
+ };
140
+ worldVelToScreen(vxMeters: any, vyMeters: any): {
141
+ x: number;
142
+ y: number;
143
+ };
144
+ step(delta: any): number;
145
+ addBody(planckBody: any, rigidBodyNode: any): void;
146
+ removeBody(planckBody: any): void;
147
+ setupCollisionEvents(): void;
148
+ queryPoint(screenX: any, screenY: any): any[];
149
+ raycastScreen(x1: any, y1: any, x2: any, y2: any): any;
150
+ }
151
+ import { Node } from "./core.js";
152
+ import { Vec2 } from "planck";
153
+ import { World } from "planck";
154
+ export {};