@caperjs/plugin-crunch 0.1.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/LICENSE +22 -0
- package/README.md +205 -0
- package/lib/Actor.d.ts +227 -0
- package/lib/Actor.d.ts.map +1 -0
- package/lib/CrunchPhysicsPlugin.d.ts +508 -0
- package/lib/CrunchPhysicsPlugin.d.ts.map +1 -0
- package/lib/Entity.d.ts +377 -0
- package/lib/Entity.d.ts.map +1 -0
- package/lib/Group.d.ts +122 -0
- package/lib/Group.d.ts.map +1 -0
- package/lib/Sensor.d.ts +161 -0
- package/lib/Sensor.d.ts.map +1 -0
- package/lib/Solid.d.ts +109 -0
- package/lib/Solid.d.ts.map +1 -0
- package/lib/System.d.ts +265 -0
- package/lib/System.d.ts.map +1 -0
- package/lib/caper-plugin-crunch.mjs +1331 -0
- package/lib/caper-plugin-crunch.mjs.map +1 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/interfaces.d.ts +32 -0
- package/lib/interfaces.d.ts.map +1 -0
- package/lib/types.d.ts +246 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/utils.d.ts +63 -0
- package/lib/utils.d.ts.map +1 -0
- package/lib/version.d.ts +2 -0
- package/lib/version.d.ts.map +1 -0
- package/package.json +42 -0
- package/src/Actor.ts +726 -0
- package/src/CrunchPhysicsPlugin.ts +718 -0
- package/src/Entity.ts +762 -0
- package/src/Group.ts +181 -0
- package/src/Sensor.ts +427 -0
- package/src/Solid.ts +380 -0
- package/src/System.ts +1546 -0
- package/src/collision-layers.d.ts +87 -0
- package/src/index.ts +18 -0
- package/src/interfaces.ts +33 -0
- package/src/types.ts +336 -0
- package/src/utils.ts +72 -0
- package/src/version.ts +1 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file provides TypeScript declaration merging for custom collision layers.
|
|
3
|
+
*
|
|
4
|
+
* To use this feature, create a declaration file in your project (e.g., collision-layers.d.ts)
|
|
5
|
+
* and extend the UserCollisionLayers interface with your custom layers:
|
|
6
|
+
*
|
|
7
|
+
* ```typescript
|
|
8
|
+
* // collision-layers.d.ts in your project
|
|
9
|
+
* declare module '@caperjs/plugin-crunch' {
|
|
10
|
+
* interface UserCollisionLayers {
|
|
11
|
+
* WATER: number;
|
|
12
|
+
* LAVA: number;
|
|
13
|
+
* CLOUD: number;
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* Then you can access your custom layers with intellisense:
|
|
19
|
+
*
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { physics } from '@caperjs/core';
|
|
22
|
+
*
|
|
23
|
+
* // Register your custom layers
|
|
24
|
+
* physics.registerCollisionLayer('WATER', 0);
|
|
25
|
+
* physics.registerCollisionLayer('LAVA', 1);
|
|
26
|
+
* physics.registerCollisionLayer('CLOUD', 2);
|
|
27
|
+
*
|
|
28
|
+
* // Access with intellisense
|
|
29
|
+
* const waterLayer = physics.getCollisionLayer('WATER');
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Interface for user-defined collision layers.
|
|
35
|
+
* Extend this interface in your own declaration files to add intellisense support
|
|
36
|
+
* for your custom collision layers.
|
|
37
|
+
*/
|
|
38
|
+
export interface UserCollisionLayers {
|
|
39
|
+
// This is intentionally empty and should be extended by users
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Extended plugin interface with intellisense support for custom collision layers
|
|
44
|
+
*/
|
|
45
|
+
export interface CollisionLayerPluginExtensions {
|
|
46
|
+
/**
|
|
47
|
+
* Gets a registered collision layer by name with intellisense support.
|
|
48
|
+
*
|
|
49
|
+
* @param name Name of the collision layer
|
|
50
|
+
* @returns The numeric value of the registered collision layer or undefined if not found
|
|
51
|
+
*/
|
|
52
|
+
getCollisionLayer<K extends keyof UserCollisionLayers>(name: K): number | undefined;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Registers a named collision layer with intellisense support.
|
|
56
|
+
*
|
|
57
|
+
* @param name Name of the collision layer
|
|
58
|
+
* @param index Index from 0-15 representing which user bit to use
|
|
59
|
+
* @param description Optional description of the layer
|
|
60
|
+
* @returns The numeric value of the registered collision layer
|
|
61
|
+
*/
|
|
62
|
+
registerCollisionLayer<K extends keyof UserCollisionLayers>(name: K, index: number, description?: string): number;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Registers a named collision layer with automatic index assignment and intellisense support.
|
|
66
|
+
*
|
|
67
|
+
* @param name Name of the collision layer
|
|
68
|
+
* @param description Optional description of the layer
|
|
69
|
+
* @returns The numeric value of the registered collision layer
|
|
70
|
+
*/
|
|
71
|
+
registerCollisionLayer<K extends keyof UserCollisionLayers>(name: K, description?: string): number;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Removes a registered collision layer with intellisense support.
|
|
75
|
+
*
|
|
76
|
+
* @param name Name of the collision layer to remove
|
|
77
|
+
* @returns True if the layer was removed, false if it didn't exist
|
|
78
|
+
*/
|
|
79
|
+
removeCollisionLayer<K extends keyof UserCollisionLayers>(name: K): boolean;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Extend the ICrunchPhysicsPlugin interface to include the CollisionLayerPluginExtensions
|
|
83
|
+
import './CrunchPhysicsPlugin';
|
|
84
|
+
|
|
85
|
+
declare module './CrunchPhysicsPlugin' {
|
|
86
|
+
interface ICrunchPhysicsPlugin extends CollisionLayerPluginExtensions {}
|
|
87
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import CrunchPhysicsPlugin from './CrunchPhysicsPlugin';
|
|
2
|
+
|
|
3
|
+
export * from './Actor';
|
|
4
|
+
// Don't export from collision-layers.d.ts as it's a declaration file
|
|
5
|
+
export * from './Entity';
|
|
6
|
+
export * from './Group';
|
|
7
|
+
export * from './interfaces';
|
|
8
|
+
export * from './Sensor';
|
|
9
|
+
export * from './Solid';
|
|
10
|
+
export * from './System';
|
|
11
|
+
export * from './types';
|
|
12
|
+
|
|
13
|
+
export type { ICrunchPhysicsPlugin } from './CrunchPhysicsPlugin';
|
|
14
|
+
|
|
15
|
+
// Export specific types for easier access
|
|
16
|
+
export * from './types';
|
|
17
|
+
|
|
18
|
+
export default CrunchPhysicsPlugin;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Container, Rectangle } from 'pixi.js';
|
|
2
|
+
import { ActorCollision, Collision, SensorOverlap } from './types';
|
|
3
|
+
|
|
4
|
+
export interface CrunchPhysicsOptions {
|
|
5
|
+
container: Container;
|
|
6
|
+
/** Grid cell size in pixels */
|
|
7
|
+
gridSize?: number;
|
|
8
|
+
/** Gravity strength */
|
|
9
|
+
gravity?: number;
|
|
10
|
+
/** Maximum velocity */
|
|
11
|
+
maxVelocity?: number;
|
|
12
|
+
/** Whether to enable debug rendering */
|
|
13
|
+
debug?: boolean;
|
|
14
|
+
/** Whether to cull out-of-bounds entities */
|
|
15
|
+
culling?: boolean;
|
|
16
|
+
/** Whether to remove entities from the system after culling */
|
|
17
|
+
boundary?: Rectangle;
|
|
18
|
+
/** Collision resolver */
|
|
19
|
+
collisionResolver?: (collisions: Collision[]) => void;
|
|
20
|
+
/** Overlap resolver */
|
|
21
|
+
overlapResolver?: (overlaps: SensorOverlap[]) => void;
|
|
22
|
+
/** Actor-to-actor collision resolver */
|
|
23
|
+
actorCollisionResolver?: (collisions: ActorCollision[]) => void;
|
|
24
|
+
/** Whether to enable actor-to-actor collisions */
|
|
25
|
+
enableActorCollisions?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface AABBLike {
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { PointLike, SizeLike } from '@caperjs/core';
|
|
2
|
+
import { Container } from 'pixi.js';
|
|
3
|
+
import { Actor } from './Actor';
|
|
4
|
+
import { Entity } from './Entity';
|
|
5
|
+
import { Group } from './Group';
|
|
6
|
+
import { Sensor } from './Sensor';
|
|
7
|
+
import { Solid } from './Solid';
|
|
8
|
+
|
|
9
|
+
export interface Vector2 {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface Rectangle {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type CollisionShape = 'rectangle';
|
|
22
|
+
export type EntityData = {
|
|
23
|
+
[key: string]: any;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type PhysicsEntityClass = new (config?: PhysicsEntityConfig) => Actor | Solid | Sensor;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Collision layers using bitwise flags
|
|
30
|
+
* Each entity can belong to multiple layers (using bitwise OR)
|
|
31
|
+
* and can collide with multiple layers (using bitwise AND)
|
|
32
|
+
*/
|
|
33
|
+
export enum CollisionLayer {
|
|
34
|
+
NONE = 0,
|
|
35
|
+
DEFAULT = 1 << 0,
|
|
36
|
+
PLAYER = 1 << 1,
|
|
37
|
+
ENEMY = 1 << 2,
|
|
38
|
+
PROJECTILE = 1 << 3,
|
|
39
|
+
PLATFORM = 1 << 4,
|
|
40
|
+
TRIGGER = 1 << 5,
|
|
41
|
+
ITEM = 1 << 6,
|
|
42
|
+
WALL = 1 << 7,
|
|
43
|
+
FX = 1 << 8,
|
|
44
|
+
// Reserve first 16 bits for built-in layers
|
|
45
|
+
// Bits 16-31 are available for user-defined layers
|
|
46
|
+
ALL = 0xffffffff, // All bits set to 1
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Interface for a registered collision layer
|
|
51
|
+
*/
|
|
52
|
+
export interface RegisteredCollisionLayer {
|
|
53
|
+
/** Name of the collision layer */
|
|
54
|
+
name: string;
|
|
55
|
+
/** Numeric value of the collision layer (bitwise) */
|
|
56
|
+
value: number;
|
|
57
|
+
/** Description of the collision layer (optional) */
|
|
58
|
+
description?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Registry for tracking custom collision layers
|
|
63
|
+
*/
|
|
64
|
+
export class CollisionLayerRegistry {
|
|
65
|
+
private static _instance: CollisionLayerRegistry;
|
|
66
|
+
private _layers: Map<string, RegisteredCollisionLayer> = new Map();
|
|
67
|
+
private _usedIndices: Set<number> = new Set();
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get the singleton instance of the registry
|
|
71
|
+
*/
|
|
72
|
+
public static get instance(): CollisionLayerRegistry {
|
|
73
|
+
if (!CollisionLayerRegistry._instance) {
|
|
74
|
+
CollisionLayerRegistry._instance = new CollisionLayerRegistry();
|
|
75
|
+
}
|
|
76
|
+
return CollisionLayerRegistry._instance;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Register a new collision layer
|
|
81
|
+
*
|
|
82
|
+
* @param name Name of the collision layer
|
|
83
|
+
* @param index Index from 0-15 representing which user bit to use (gets shifted to bits 16-31)
|
|
84
|
+
* @param description Optional description of the layer
|
|
85
|
+
* @returns The registered collision layer
|
|
86
|
+
*/
|
|
87
|
+
public register(name: string, index: number, description?: string): RegisteredCollisionLayer {
|
|
88
|
+
if (index < 0 || index > 15) {
|
|
89
|
+
throw new Error('Custom collision layer index must be between 0 and 15');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (this._usedIndices.has(index)) {
|
|
93
|
+
throw new Error(`Collision layer index ${index} is already in use`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (this._layers.has(name)) {
|
|
97
|
+
throw new Error(`Collision layer with name "${name}" already exists`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const value = 1 << (index + 16);
|
|
101
|
+
const layer: RegisteredCollisionLayer = { name, value, description };
|
|
102
|
+
|
|
103
|
+
this._layers.set(name, layer);
|
|
104
|
+
this._usedIndices.add(index);
|
|
105
|
+
|
|
106
|
+
return layer;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get a registered collision layer by name
|
|
111
|
+
*
|
|
112
|
+
* @param name Name of the collision layer
|
|
113
|
+
* @returns The registered collision layer or undefined if not found
|
|
114
|
+
*/
|
|
115
|
+
public get(name: string): RegisteredCollisionLayer | undefined {
|
|
116
|
+
return this._layers.get(name);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Get all registered collision layers
|
|
121
|
+
*
|
|
122
|
+
* @returns Array of all registered collision layers
|
|
123
|
+
*/
|
|
124
|
+
public getAll(): RegisteredCollisionLayer[] {
|
|
125
|
+
return Array.from(this._layers.values());
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Check if a collision layer with the given name exists
|
|
130
|
+
*
|
|
131
|
+
* @param name Name of the collision layer
|
|
132
|
+
* @returns True if the layer exists
|
|
133
|
+
*/
|
|
134
|
+
public has(name: string): boolean {
|
|
135
|
+
return this._layers.has(name);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Remove a registered collision layer
|
|
140
|
+
*
|
|
141
|
+
* @param name Name of the collision layer to remove
|
|
142
|
+
* @returns True if the layer was removed, false if it didn't exist
|
|
143
|
+
*/
|
|
144
|
+
public remove(name: string): boolean {
|
|
145
|
+
const layer = this._layers.get(name);
|
|
146
|
+
if (!layer) return false;
|
|
147
|
+
|
|
148
|
+
// Calculate the index from the value
|
|
149
|
+
const value = layer.value;
|
|
150
|
+
const index = Math.log2(value) - 16;
|
|
151
|
+
|
|
152
|
+
this._usedIndices.delete(index);
|
|
153
|
+
return this._layers.delete(name);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Clear all registered collision layers
|
|
158
|
+
*/
|
|
159
|
+
public clear(): void {
|
|
160
|
+
this._layers.clear();
|
|
161
|
+
this._usedIndices.clear();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Get the next available index for a custom collision layer
|
|
166
|
+
*
|
|
167
|
+
* @returns The next available index or -1 if all indices are used
|
|
168
|
+
*/
|
|
169
|
+
public getNextAvailableIndex(): number {
|
|
170
|
+
for (let i = 0; i < 16; i++) {
|
|
171
|
+
if (!this._usedIndices.has(i)) {
|
|
172
|
+
return i;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return -1;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Utility functions for working with collision layers
|
|
181
|
+
*/
|
|
182
|
+
export const CollisionLayers = {
|
|
183
|
+
/**
|
|
184
|
+
* Creates a custom collision layer using bits 16-31 (user space)
|
|
185
|
+
*
|
|
186
|
+
* @param index Index from 0-15 representing which user bit to use (gets shifted to bits 16-31)
|
|
187
|
+
* @returns A unique collision layer value
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* // Create custom collision layers
|
|
192
|
+
* const WATER_LAYER = CollisionLayers.createLayer(0); // 1 << 16
|
|
193
|
+
* const LAVA_LAYER = CollisionLayers.createLayer(1); // 1 << 17
|
|
194
|
+
* const CLOUD_LAYER = CollisionLayers.createLayer(2); // 1 << 18
|
|
195
|
+
*
|
|
196
|
+
* // Use in entity creation
|
|
197
|
+
* const waterEntity = physics.createActor({
|
|
198
|
+
* type: 'Water',
|
|
199
|
+
* position: [100, 400],
|
|
200
|
+
* size: [800, 100],
|
|
201
|
+
* collisionLayer: WATER_LAYER,
|
|
202
|
+
* collisionMask: CollisionLayer.PLAYER | CollisionLayer.ENEMY
|
|
203
|
+
* });
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
createLayer(index: number): number {
|
|
207
|
+
if (index < 0 || index > 15) {
|
|
208
|
+
throw new Error('Custom collision layer index must be between 0 and 15');
|
|
209
|
+
}
|
|
210
|
+
return 1 << (index + 16);
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Creates a collision mask from multiple layers
|
|
215
|
+
*
|
|
216
|
+
* @param layers Array of collision layers to combine
|
|
217
|
+
* @returns A combined collision mask
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* // Create a mask that collides with players, enemies and projectiles
|
|
222
|
+
* const mask = CollisionLayers.createMask([
|
|
223
|
+
* CollisionLayer.PLAYER,
|
|
224
|
+
* CollisionLayer.ENEMY,
|
|
225
|
+
* CollisionLayer.PROJECTILE
|
|
226
|
+
* ]);
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
createMask(layers: number[]): number {
|
|
230
|
+
return layers.reduce((mask, layer) => mask | layer, 0);
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Checks if a layer is included in a mask
|
|
235
|
+
*
|
|
236
|
+
* @param layer The layer to check
|
|
237
|
+
* @param mask The mask to check against
|
|
238
|
+
* @returns True if the layer is included in the mask
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* // Check if player layer is in the mask
|
|
243
|
+
* if (CollisionLayers.isLayerInMask(CollisionLayer.PLAYER, entity.collisionMask)) {
|
|
244
|
+
* console.log('Entity can collide with players');
|
|
245
|
+
* }
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
isLayerInMask(layer: number, mask: number): boolean {
|
|
249
|
+
return (layer & mask) !== 0;
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Get the registry for custom collision layers
|
|
254
|
+
*
|
|
255
|
+
* @returns The collision layer registry
|
|
256
|
+
*/
|
|
257
|
+
getRegistry(): CollisionLayerRegistry {
|
|
258
|
+
return CollisionLayerRegistry.instance;
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
export interface PhysicsEntityConfig<D extends EntityData = EntityData> {
|
|
263
|
+
id?: string;
|
|
264
|
+
class?: PhysicsEntityClass;
|
|
265
|
+
type?: PhysicsEntityType;
|
|
266
|
+
position?: PointLike;
|
|
267
|
+
size?: SizeLike;
|
|
268
|
+
x?: number;
|
|
269
|
+
y?: number;
|
|
270
|
+
width?: number;
|
|
271
|
+
height?: number;
|
|
272
|
+
restitution?: number;
|
|
273
|
+
view?: PhysicsEntityView;
|
|
274
|
+
data?: Partial<D>;
|
|
275
|
+
group?: Group;
|
|
276
|
+
groupOffset?: PointLike;
|
|
277
|
+
follows?: Entity;
|
|
278
|
+
followOffset?: PointLike;
|
|
279
|
+
/** Collision layer this entity belongs to (bitwise) */
|
|
280
|
+
collisionLayer?: number;
|
|
281
|
+
/** Collision mask defining which layers this entity collides with (bitwise) */
|
|
282
|
+
collisionMask?: number;
|
|
283
|
+
/** Whether to disable actor-to-actor collisions for this entity */
|
|
284
|
+
disableActorCollisions?: boolean;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export interface CollisionResult {
|
|
288
|
+
collided: boolean;
|
|
289
|
+
normal?: Vector2;
|
|
290
|
+
penetration?: number;
|
|
291
|
+
solid: Solid;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export interface SensorOverlap {
|
|
295
|
+
type: `${PhysicsEntityType}|${PhysicsEntityType}`;
|
|
296
|
+
actor: Actor;
|
|
297
|
+
sensor: Sensor;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export interface CollisionResult {
|
|
301
|
+
collided: boolean;
|
|
302
|
+
normal?: Vector2;
|
|
303
|
+
penetration?: number;
|
|
304
|
+
solid: Solid;
|
|
305
|
+
pushingSolid?: Solid;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Result of an actor-to-actor collision
|
|
310
|
+
*/
|
|
311
|
+
export interface ActorCollisionResult {
|
|
312
|
+
collided: boolean;
|
|
313
|
+
normal?: Vector2;
|
|
314
|
+
penetration?: number;
|
|
315
|
+
actor: Actor;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export interface Collision {
|
|
319
|
+
type: `${PhysicsEntityType}|${PhysicsEntityType}`;
|
|
320
|
+
entity1: Actor | Sensor;
|
|
321
|
+
entity2: Actor | Solid;
|
|
322
|
+
result: CollisionResult;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Represents a collision between two actors
|
|
327
|
+
*/
|
|
328
|
+
export interface ActorCollision {
|
|
329
|
+
type: `${PhysicsEntityType}|${PhysicsEntityType}`;
|
|
330
|
+
actor1: Actor;
|
|
331
|
+
actor2: Actor;
|
|
332
|
+
result: ActorCollisionResult;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export type PhysicsEntityView = Container;
|
|
336
|
+
export type PhysicsEntityType = 'Actor' | 'Solid' | 'Sensor' | 'Group' | string;
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { resolvePointLike, resolveSizeLike } from '@caperjs/core';
|
|
2
|
+
import { PhysicsEntityConfig } from './types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Utility functions for resolving entity positions and sizes from various input formats.
|
|
6
|
+
* These functions handle the conversion of different coordinate and size specifications
|
|
7
|
+
* into standardized formats used by the physics system.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Resolves an entity's position from various input formats.
|
|
12
|
+
* Supports direct x/y values or a position object/array.
|
|
13
|
+
*
|
|
14
|
+
* @param config - Entity configuration containing position information
|
|
15
|
+
* @returns Resolved {x, y} coordinates
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* // Using direct x/y values
|
|
20
|
+
* resolveEntityPosition({ x: 100, y: 200 })
|
|
21
|
+
* // → { x: 100, y: 200 }
|
|
22
|
+
*
|
|
23
|
+
* // Using position array
|
|
24
|
+
* resolveEntityPosition({ position: [100, 200] })
|
|
25
|
+
* // → { x: 100, y: 200 }
|
|
26
|
+
*
|
|
27
|
+
* // Using position object
|
|
28
|
+
* resolveEntityPosition({ position: { x: 100, y: 200 } })
|
|
29
|
+
* // → { x: 100, y: 200 }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function resolveEntityPosition(config: PhysicsEntityConfig): { x: number; y: number } {
|
|
33
|
+
const { x, y } =
|
|
34
|
+
config.position !== undefined ? resolvePointLike(config.position) : { x: config?.x ?? 0, y: config?.y ?? 0 };
|
|
35
|
+
|
|
36
|
+
return { x, y };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Resolves an entity's size from various input formats.
|
|
41
|
+
* Supports direct width/height values or a size object/array.
|
|
42
|
+
*
|
|
43
|
+
* @param config - Entity configuration containing size information
|
|
44
|
+
* @returns Resolved {width, height} dimensions
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* // Using direct width/height values
|
|
49
|
+
* resolveEntitySize({ width: 100, height: 200 })
|
|
50
|
+
* // → { width: 100, height: 200 }
|
|
51
|
+
*
|
|
52
|
+
* // Using size array
|
|
53
|
+
* resolveEntitySize({ size: [100, 200] })
|
|
54
|
+
* // → { width: 100, height: 200 }
|
|
55
|
+
*
|
|
56
|
+
* // Using size object
|
|
57
|
+
* resolveEntitySize({ size: { width: 100, height: 200 } })
|
|
58
|
+
* // → { width: 100, height: 200 }
|
|
59
|
+
*
|
|
60
|
+
* // Using defaults
|
|
61
|
+
* resolveEntitySize({})
|
|
62
|
+
* // → { width: 32, height: 32 }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export function resolveEntitySize(config: PhysicsEntityConfig): { width: number; height: number } {
|
|
66
|
+
const { width, height } =
|
|
67
|
+
config.size !== undefined
|
|
68
|
+
? resolveSizeLike(config.size)
|
|
69
|
+
: { width: config?.width ?? 32, height: config?.height ?? 32 };
|
|
70
|
+
|
|
71
|
+
return { width, height };
|
|
72
|
+
}
|
package/src/version.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const version = '0.1.0';
|