@ue-too/dynamics 0.9.5 → 0.11.0

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/README.md CHANGED
@@ -1,7 +1,541 @@
1
- # dynamics
1
+ # @ue-too/dynamics
2
2
 
3
- This is a library that provides a 2D physics engine with collision detection, rigid bodies, and constraints.
3
+ 2D physics engine with rigid body dynamics and collision detection.
4
4
 
5
- Please _**DO NOT**_ use this in production.
5
+ [![npm version](https://img.shields.io/npm/v/@ue-too/dynamics.svg)](https://www.npmjs.com/package/@ue-too/dynamics)
6
+ [![license](https://img.shields.io/npm/l/@ue-too/dynamics.svg)](https://github.com/ue-too/ue-too/blob/main/LICENSE.txt)
6
7
 
7
- Detailed information would be added in the future.
8
+ > **Experimental**: This package is an experimental implementation. Please **DO NOT** use this in production.
9
+
10
+ ## Overview
11
+
12
+ `@ue-too/dynamics` provides a complete 2D physics simulation engine featuring rigid body dynamics, collision detection, constraint solving, and performance optimizations like spatial indexing and sleeping bodies.
13
+
14
+ ### Key Features
15
+
16
+ - **Rigid Body Physics**: Linear and angular velocity, mass, moment of inertia
17
+ - **Collision Detection**: Broad phase (spatial indexing) + narrow phase (SAT)
18
+ - **Collision Response**: Impulse-based resolution with friction and restitution
19
+ - **Constraints**: Pin joints (fixed and between bodies) with Baumgarte stabilization
20
+ - **Spatial Indexing**: QuadTree, Dynamic Tree, and Sweep-and-Prune algorithms
21
+ - **Sleeping System**: Automatically disable resting bodies for performance
22
+ - **Collision Filtering**: Category-based filtering with masks and groups
23
+ - **Shape Types**: Circles and convex polygons
24
+
25
+ ## Installation
26
+
27
+ Using Bun:
28
+ ```bash
29
+ bun add @ue-too/dynamics
30
+ ```
31
+
32
+ Using npm:
33
+ ```bash
34
+ npm install @ue-too/dynamics
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ Here's a simple example creating a physics world with a falling ball:
40
+
41
+ ```typescript
42
+ import { World, Circle, Polygon } from '@ue-too/dynamics';
43
+
44
+ // Create a physics world (2000x2000 world size)
45
+ const world = new World(2000, 2000, 'dynamictree');
46
+
47
+ // Create static ground
48
+ const ground = new Polygon(
49
+ { x: 0, y: -100 }, // Position
50
+ [ // Vertices (local space)
51
+ { x: -1000, y: 0 },
52
+ { x: 1000, y: 0 },
53
+ { x: 1000, y: 50 },
54
+ { x: -1000, y: 50 }
55
+ ],
56
+ 0, // Rotation
57
+ 100, // Mass (ignored for static bodies)
58
+ true // isStatic
59
+ );
60
+ world.addRigidBody('ground', ground);
61
+
62
+ // Create dynamic ball
63
+ const ball = new Circle(
64
+ { x: 0, y: 200 }, // Position
65
+ 20, // Radius
66
+ 0, // Rotation
67
+ 10, // Mass
68
+ false // isStatic
69
+ );
70
+ world.addRigidBody('ball', ball);
71
+
72
+ // Simulation loop (60 FPS)
73
+ setInterval(() => {
74
+ world.step(1/60); // deltaTime in seconds
75
+
76
+ console.log('Ball position:', ball.position);
77
+ }, 16);
78
+ ```
79
+
80
+ ## Core Concepts
81
+
82
+ ### Rigid Bodies
83
+
84
+ Rigid bodies are objects that don't deform. They have:
85
+
86
+ - **Position**: World coordinates
87
+ - **Rotation**: Angle in radians
88
+ - **Velocity**: Linear velocity vector
89
+ - **Angular Velocity**: Rotation speed in radians/second
90
+ - **Mass**: Affects how much force is needed to move the body
91
+ - **Moment of Inertia**: Resistance to rotational acceleration
92
+
93
+ ### Static vs Dynamic Bodies
94
+
95
+ - **Static**: Don't move, infinite mass (walls, floors, platforms)
96
+ - **Dynamic**: Move and respond to forces (players, projectiles, debris)
97
+ - **Kinematic**: Move but don't respond to collisions (moving platforms)
98
+
99
+ ### Collision Detection Phases
100
+
101
+ 1. **Broad Phase**: Uses spatial indexing to quickly find potentially colliding pairs
102
+ - QuadTree: Good for static worlds
103
+ - Dynamic Tree: Good for mixed static/dynamic
104
+ - Sweep-and-Prune: Best for many dynamic bodies
105
+
106
+ 2. **Narrow Phase**: Precise collision detection using Separating Axis Theorem (SAT)
107
+
108
+ ### Collision Filtering
109
+
110
+ Bodies can be filtered by:
111
+ - **Category**: What category this body belongs to (bit flags)
112
+ - **Mask**: Which categories this body collides with (bit flags)
113
+ - **Group**: Positive groups collide only with same group, negative never collide
114
+
115
+ ## Core APIs
116
+
117
+ ### World Class
118
+
119
+ Main physics world container.
120
+
121
+ **Constructor:**
122
+ ```typescript
123
+ const world = new World(
124
+ worldWidth: number,
125
+ worldHeight: number,
126
+ spatialIndexType?: 'quadtree' | 'dynamictree' | 'sap'
127
+ );
128
+ ```
129
+
130
+ **Methods:**
131
+ - `step(deltaTime: number)`: Advance simulation by deltaTime seconds
132
+ - `addRigidBody(id: string, body: RigidBody)`: Add a rigid body
133
+ - `removeRigidBody(id: string)`: Remove a rigid body
134
+ - `addConstraint(constraint: Constraint)`: Add a constraint
135
+ - `removeConstraint(constraint: Constraint)`: Remove a constraint
136
+ - `setSpatialIndexType(type)`: Change spatial indexing algorithm
137
+ - `queryAABB(aabb): RigidBody[]`: Find all bodies in an AABB region
138
+ - `queryPoint(point): RigidBody[]`: Find all bodies containing a point
139
+ - `rayCast(from, to): RayCastResult[]`: Ray casting
140
+
141
+ **Properties:**
142
+ - `gravity: Point`: World gravity vector (default: `{x: 0, y: -9.8}`)
143
+ - `sleepingEnabled: boolean`: Enable/disable sleeping system
144
+ - `bodies: Map<string, RigidBody>`: All bodies in the world
145
+ - `constraints: Constraint[]`: All constraints
146
+
147
+ ### Circle Class
148
+
149
+ Circular rigid body.
150
+
151
+ **Constructor:**
152
+ ```typescript
153
+ const circle = new Circle(
154
+ position: Point,
155
+ radius: number,
156
+ rotation: number,
157
+ mass: number,
158
+ isStatic: boolean
159
+ );
160
+ ```
161
+
162
+ **Properties:**
163
+ - `position: Point`: World position
164
+ - `velocity: Point`: Linear velocity
165
+ - `rotation: number`: Rotation in radians
166
+ - `angularVelocity: number`: Rotation speed
167
+ - `mass: number`: Mass (0 for static bodies)
168
+ - `radius: number`: Circle radius
169
+ - `restitution: number`: Bounciness (0-1)
170
+ - `friction: number`: Friction coefficient
171
+ - `collisionFilter: CollisionFilter`: Filtering
172
+
173
+ ### Polygon Class
174
+
175
+ Convex polygon rigid body.
176
+
177
+ **Constructor:**
178
+ ```typescript
179
+ const polygon = new Polygon(
180
+ position: Point,
181
+ vertices: Point[], // Local space vertices
182
+ rotation: number,
183
+ mass: number,
184
+ isStatic: boolean
185
+ );
186
+ ```
187
+
188
+ **Properties:**
189
+ - Same as Circle, plus:
190
+ - `vertices: Point[]`: Vertices in local space
191
+ - `worldVertices: Point[]`: Vertices in world space (computed)
192
+
193
+ **Methods:**
194
+ - `updateWorldVertices()`: Recompute world vertices after transform changes
195
+
196
+ ### Constraints
197
+
198
+ #### PinJoint
199
+
200
+ Pin joint between two bodies.
201
+
202
+ ```typescript
203
+ const joint = new PinJoint(
204
+ bodyA: RigidBody,
205
+ bodyB: RigidBody,
206
+ anchorA: Point, // Local anchor on bodyA
207
+ anchorB: Point // Local anchor on bodyB
208
+ );
209
+ ```
210
+
211
+ #### FixedPinJoint
212
+
213
+ Pin joint from body to world point.
214
+
215
+ ```typescript
216
+ const fixedJoint = new FixedPinJoint(
217
+ body: RigidBody,
218
+ localAnchor: Point, // Local anchor on body
219
+ worldAnchor: Point // Fixed world position
220
+ );
221
+ ```
222
+
223
+ ### Collision Filter
224
+
225
+ ```typescript
226
+ type CollisionFilter = {
227
+ category: number; // What category this body is (bit flags)
228
+ mask: number; // What categories to collide with (bit flags)
229
+ group: number; // Collision group
230
+ };
231
+ ```
232
+
233
+ **Predefined Categories:**
234
+ ```typescript
235
+ enum CollisionCategory {
236
+ STATIC = 0x0001,
237
+ PLAYER = 0x0002,
238
+ ENEMY = 0x0004,
239
+ PROJECTILE = 0x0008,
240
+ SENSOR = 0x0010,
241
+ PLATFORM = 0x0020
242
+ }
243
+ ```
244
+
245
+ ## Common Use Cases
246
+
247
+ ### Basic Platformer Physics
248
+
249
+ ```typescript
250
+ import { World, Circle, Polygon, CollisionCategory } from '@ue-too/dynamics';
251
+
252
+ const world = new World(2000, 2000, 'dynamictree');
253
+ world.gravity = { x: 0, y: -20 }; // Downward gravity
254
+
255
+ // Ground
256
+ const ground = new Polygon(
257
+ { x: 0, y: -150 },
258
+ [{ x: -500, y: 0 }, { x: 500, y: 0 }, { x: 500, y: 50 }, { x: -500, y: 50 }],
259
+ 0, 0, true
260
+ );
261
+ ground.collisionFilter = {
262
+ category: CollisionCategory.STATIC,
263
+ mask: 0xFFFF, // Collides with everything
264
+ group: 0
265
+ };
266
+ world.addRigidBody('ground', ground);
267
+
268
+ // Player
269
+ const player = new Circle({ x: 0, y: 0 }, 20, 0, 10, false);
270
+ player.collisionFilter = {
271
+ category: CollisionCategory.PLAYER,
272
+ mask: CollisionCategory.STATIC | CollisionCategory.PLATFORM | CollisionCategory.ENEMY,
273
+ group: 0
274
+ };
275
+ player.restitution = 0; // No bounce
276
+ player.friction = 0.5;
277
+ world.addRigidBody('player', player);
278
+
279
+ // Apply jump force
280
+ function jump() {
281
+ player.velocity.y = 15; // Upward velocity
282
+ }
283
+
284
+ // Game loop
285
+ function update(deltaTime: number) {
286
+ world.step(deltaTime);
287
+ // Render player at player.position
288
+ }
289
+ ```
290
+
291
+ ### Pendulum with Constraints
292
+
293
+ ```typescript
294
+ import { World, Circle, FixedPinJoint } from '@ue-too/dynamics';
295
+
296
+ const world = new World(2000, 2000);
297
+ world.gravity = { x: 0, y: -9.8 };
298
+
299
+ // Pendulum bob
300
+ const bob = new Circle({ x: 0, y: 100 }, 20, 0, 10, false);
301
+ bob.restitution = 0.8; // Bouncy
302
+ world.addRigidBody('bob', bob);
303
+
304
+ // Fix to world origin
305
+ const joint = new FixedPinJoint(
306
+ bob,
307
+ { x: 0, y: 0 }, // Bob's center
308
+ { x: 0, y: 0 } // World origin
309
+ );
310
+ world.addConstraint(joint);
311
+
312
+ // Simulation
313
+ function update(deltaTime: number) {
314
+ world.step(deltaTime);
315
+ }
316
+ ```
317
+
318
+ ### Chain of Bodies
319
+
320
+ ```typescript
321
+ import { World, Circle, PinJoint } from '@ue-too/dynamics';
322
+
323
+ const world = new World(2000, 2000);
324
+ world.gravity = { x: 0, y: -9.8 };
325
+
326
+ const links: Circle[] = [];
327
+ const numLinks = 5;
328
+
329
+ // Create chain links
330
+ for (let i = 0; i < numLinks; i++) {
331
+ const link = new Circle({ x: i * 30, y: 0 }, 10, 0, 5, false);
332
+ world.addRigidBody(`link${i}`, link);
333
+ links.push(link);
334
+
335
+ if (i > 0) {
336
+ // Connect to previous link
337
+ const joint = new PinJoint(
338
+ links[i - 1],
339
+ links[i],
340
+ { x: 10, y: 0 }, // Right edge of previous
341
+ { x: -10, y: 0 } // Left edge of current
342
+ );
343
+ world.addConstraint(joint);
344
+ }
345
+ }
346
+
347
+ // Fix first link to world
348
+ const fixedJoint = new FixedPinJoint(
349
+ links[0],
350
+ { x: -10, y: 0 },
351
+ { x: 0, y: 0 }
352
+ );
353
+ world.addConstraint(fixedJoint);
354
+ ```
355
+
356
+ ### Collision Sensors
357
+
358
+ ```typescript
359
+ import { Circle, CollisionCategory } from '@ue-too/dynamics';
360
+
361
+ // Create a trigger zone that doesn't physically collide
362
+ const trigger = new Circle({ x: 100, y: 100 }, 50, 0, 0, true);
363
+ trigger.collisionFilter = {
364
+ category: CollisionCategory.SENSOR,
365
+ mask: CollisionCategory.PLAYER,
366
+ group: -1 // Negative group = never physically collide
367
+ };
368
+ world.addRigidBody('trigger', trigger);
369
+
370
+ // Listen for collisions
371
+ world.onCollision((bodyA, bodyB, contacts) => {
372
+ if (bodyA === trigger || bodyB === trigger) {
373
+ console.log('Player entered trigger zone!');
374
+ }
375
+ });
376
+ ```
377
+
378
+ ### Spatial Queries
379
+
380
+ ```typescript
381
+ // Find all bodies in a region
382
+ const aabb = {
383
+ min: { x: -50, y: -50 },
384
+ max: { x: 50, y: 50 }
385
+ };
386
+ const bodiesInRegion = world.queryAABB(aabb);
387
+
388
+ // Find bodies at a point
389
+ const bodiesAtPoint = world.queryPoint({ x: 100, y: 100 });
390
+
391
+ // Ray cast
392
+ const rayResults = world.rayCast(
393
+ { x: 0, y: 0 }, // From
394
+ { x: 100, y: 100 } // To
395
+ );
396
+
397
+ rayResults.forEach(result => {
398
+ console.log('Hit:', result.body, 'at distance:', result.distance);
399
+ });
400
+ ```
401
+
402
+ ### Performance Tuning
403
+
404
+ ```typescript
405
+ import { World } from '@ue-too/dynamics';
406
+
407
+ const world = new World(2000, 2000, 'sap'); // Sweep-and-prune for many dynamic bodies
408
+
409
+ // Enable sleeping
410
+ world.sleepingEnabled = true;
411
+
412
+ // Customize sleeping thresholds per body
413
+ body.sleepThreshold = 0.01; // Velocity threshold
414
+ body.sleepTime = 0.5; // Seconds at rest before sleeping
415
+
416
+ // Get performance stats
417
+ const stats = world.getCollisionStats();
418
+ console.log('Broad phase pairs:', stats.broadPhasePairs);
419
+ console.log('Narrow phase tests:', stats.narrowPhaseTests);
420
+ console.log('Active collisions:', stats.activeCollisions);
421
+ console.log('Sleeping bodies:', stats.sleepingBodies);
422
+
423
+ // Switch spatial index at runtime
424
+ world.setSpatialIndexType('dynamictree');
425
+ ```
426
+
427
+ ## API Reference
428
+
429
+ For complete API documentation with detailed type information, see the [TypeDoc-generated documentation](../../docs/dynamics).
430
+
431
+ ## TypeScript Support
432
+
433
+ This package is written in TypeScript with complete type definitions:
434
+
435
+ ```typescript
436
+ import {
437
+ World,
438
+ Circle,
439
+ Polygon,
440
+ RigidBody,
441
+ Constraint,
442
+ CollisionCategory,
443
+ type Point
444
+ } from '@ue-too/dynamics';
445
+
446
+ // Bodies are fully typed
447
+ const circle: Circle = new Circle({ x: 0, y: 0 }, 20, 0, 10, false);
448
+ const polygon: Polygon = new Polygon(/* ... */);
449
+
450
+ // Constraints are typed
451
+ const joint: Constraint = new PinJoint(circle, polygon, { x: 0, y: 0 }, { x: 0, y: 0 });
452
+
453
+ // Filters are typed
454
+ circle.collisionFilter = {
455
+ category: CollisionCategory.PLAYER,
456
+ mask: CollisionCategory.STATIC | CollisionCategory.ENEMY,
457
+ group: 0
458
+ };
459
+ ```
460
+
461
+ ## Design Philosophy
462
+
463
+ This physics engine follows these principles:
464
+
465
+ - **Simplicity**: Focus on common 2D game physics use cases
466
+ - **Performance**: Spatial indexing and sleeping for scalability
467
+ - **Modularity**: Pluggable spatial index algorithms
468
+ - **Practicality**: Designed for games, not scientific simulation
469
+ - **Type Safety**: Full TypeScript support
470
+
471
+ ## Performance Considerations
472
+
473
+ - **Spatial Indexing**: Choose based on your use case:
474
+ - QuadTree: Static worlds with few dynamic objects
475
+ - Dynamic Tree: Mixed static/dynamic (recommended default)
476
+ - Sweep-and-Prune: Many dynamic objects moving continuously
477
+
478
+ - **Sleeping System**: Automatically disables physics for resting bodies
479
+ - **Collision Filtering**: Reduces narrow phase tests significantly
480
+ - **Fixed Time Step**: Use fixed time steps (1/60) for stability
481
+
482
+ **Performance Tips:**
483
+ - Enable sleeping for worlds with many resting bodies
484
+ - Use collision filtering to avoid unnecessary collision tests
485
+ - Choose appropriate spatial index for your scenario
486
+ - Avoid very large mass ratios between bodies (causes instability)
487
+ - Use static bodies for immovable objects
488
+ - Limit polygon vertex counts (4-8 vertices is optimal)
489
+
490
+ ## Limitations
491
+
492
+ - **2D Only**: No 3D support
493
+ - **Convex Polygons**: Concave shapes must be decomposed
494
+ - **No Continuous Collision**: Fast-moving objects may tunnel
495
+ - **Simple Friction Model**: Basic static and dynamic friction
496
+ - **Experimental**: Not production-ready, API may change
497
+
498
+ ## Debugging Tips
499
+
500
+ ```typescript
501
+ // Enable debug rendering
502
+ world.debugDraw = (ctx: CanvasRenderingContext2D) => {
503
+ // Draw all bodies
504
+ world.bodies.forEach(body => {
505
+ ctx.strokeStyle = body.isStatic ? 'gray' : 'blue';
506
+ if (body instanceof Circle) {
507
+ ctx.beginPath();
508
+ ctx.arc(body.position.x, body.position.y, body.radius, 0, Math.PI * 2);
509
+ ctx.stroke();
510
+ } else if (body instanceof Polygon) {
511
+ ctx.beginPath();
512
+ ctx.moveTo(body.worldVertices[0].x, body.worldVertices[0].y);
513
+ for (let i = 1; i < body.worldVertices.length; i++) {
514
+ ctx.lineTo(body.worldVertices[i].x, body.worldVertices[i].y);
515
+ }
516
+ ctx.closePath();
517
+ ctx.stroke();
518
+ }
519
+ });
520
+ };
521
+ ```
522
+
523
+ ## Related Packages
524
+
525
+ - **[@ue-too/math](../math)**: Vector operations used throughout the physics engine
526
+ - **[@ue-too/ecs](../ecs)**: Entity Component System that can integrate with physics
527
+ - **[@ue-too/board](../board)**: Canvas board for rendering physics simulations
528
+
529
+ ## Further Reading
530
+
531
+ - [2D Game Physics](https://gamedevelopment.tutsplus.com/series/how-to-create-a-custom-physics-engine--gamedev-12715) - Tutorial series on 2D physics engines
532
+ - [Impulse-Based Dynamics](https://www.myphysicslab.com/engine2D/collision-en.html) - Physics engine theory
533
+ - [Separating Axis Theorem](https://en.wikipedia.org/wiki/Hyperplane_separation_theorem) - Collision detection algorithm
534
+
535
+ ## License
536
+
537
+ MIT
538
+
539
+ ## Repository
540
+
541
+ [https://github.com/ue-too/ue-too](https://github.com/ue-too/ue-too)
@@ -1,10 +1,125 @@
1
+ /**
2
+ * Collision filtering configuration for rigid bodies.
3
+ *
4
+ * @remarks
5
+ * Collision filters use a bitmask system to control which bodies can collide
6
+ * with each other. This is useful for creating layers, groups, and special
7
+ * collision rules in your physics simulation.
8
+ *
9
+ * ### How Filtering Works
10
+ *
11
+ * Two bodies A and B can collide if ALL of these conditions are met:
12
+ * 1. `(A.category & B.mask) !== 0` - A's category matches B's mask
13
+ * 2. `(B.category & A.mask) !== 0` - B's category matches A's mask
14
+ * 3. Group rules are satisfied (see group field)
15
+ *
16
+ * @category Types
17
+ */
1
18
  export interface CollisionFilter {
19
+ /**
20
+ * What category this body belongs to (bitmask).
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * category: CollisionCategory.PLAYER // 0x0004
25
+ * ```
26
+ */
2
27
  category: number;
28
+ /**
29
+ * What categories this body can collide with (bitmask).
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // Collide with everything except other players
34
+ * mask: ~CollisionCategory.PLAYER & 0xFFFF
35
+ * ```
36
+ */
3
37
  mask: number;
38
+ /**
39
+ * Collision group for special rules.
40
+ * - 0: No group (use category/mask rules)
41
+ * - Positive: Bodies in same group ALWAYS collide
42
+ * - Negative: Bodies in same group NEVER collide
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * // Ragdoll parts shouldn't collide with each other
47
+ * group: -1
48
+ *
49
+ * // Team members always collide (for physics interactions)
50
+ * group: 1
51
+ * ```
52
+ */
4
53
  group: number;
5
54
  }
55
+ /**
56
+ * Default collision filter that collides with everything.
57
+ *
58
+ * @remarks
59
+ * Uses category 0x0001 and mask 0xFFFF, meaning it belongs to the first
60
+ * category and can collide with all 16 categories.
61
+ *
62
+ * @category Collision
63
+ */
6
64
  export declare const DEFAULT_COLLISION_FILTER: CollisionFilter;
65
+ /**
66
+ * Determines if two bodies can collide based on their collision filters.
67
+ *
68
+ * @remarks
69
+ * Checks group rules first, then falls back to category/mask matching.
70
+ * This is used internally by the physics engine during broad phase collision detection.
71
+ *
72
+ * @param filterA - Collision filter of first body
73
+ * @param filterB - Collision filter of second body
74
+ * @returns True if the bodies should collide
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const player: CollisionFilter = {
79
+ * category: CollisionCategory.PLAYER,
80
+ * mask: 0xFFFF,
81
+ * group: 0
82
+ * };
83
+ *
84
+ * const enemy: CollisionFilter = {
85
+ * category: CollisionCategory.ENEMY,
86
+ * mask: CollisionCategory.PLAYER | CollisionCategory.STATIC,
87
+ * group: 0
88
+ * };
89
+ *
90
+ * console.log(canCollide(player, enemy)); // true
91
+ * ```
92
+ *
93
+ * @category Collision
94
+ */
7
95
  export declare function canCollide(filterA: CollisionFilter, filterB: CollisionFilter): boolean;
96
+ /**
97
+ * Predefined collision categories for common game entities.
98
+ *
99
+ * @remarks
100
+ * These are bitmask constants (powers of 2) that can be combined using bitwise OR.
101
+ * You can define up to 16 categories using values from 0x0001 to 0x8000.
102
+ *
103
+ * @example
104
+ * Using predefined categories
105
+ * ```typescript
106
+ * // Player collides with everything except other players
107
+ * player.collisionFilter = {
108
+ * category: CollisionCategory.PLAYER,
109
+ * mask: ~CollisionCategory.PLAYER & 0xFFFF,
110
+ * group: 0
111
+ * };
112
+ *
113
+ * // Projectile only collides with enemies and static objects
114
+ * projectile.collisionFilter = {
115
+ * category: CollisionCategory.PROJECTILE,
116
+ * mask: CollisionCategory.ENEMY | CollisionCategory.STATIC,
117
+ * group: 0
118
+ * };
119
+ * ```
120
+ *
121
+ * @category Collision
122
+ */
8
123
  export declare const CollisionCategory: {
9
124
  readonly STATIC: 1;
10
125
  readonly DYNAMIC: 2;