@dill-pixel/plugin-crunch-physics
Version:
Crunch Physics
508 lines • 16.6 kB
TypeScript
import { Application, IApplication, IPlugin, Plugin } from 'dill-pixel';
import { Container as PIXIContainer } from 'pixi.js';
import { Actor } from './Actor';
import { Group } from './Group';
import { AABBLike, CrunchPhysicsOptions } from './interfaces';
import { Sensor } from './Sensor';
import { Solid } from './Solid';
import { System } from './System';
import { ActorCollision, Collision, PhysicsEntityConfig, RegisteredCollisionLayer } from './types';
/**
* Interface for the Crunch physics plugin, providing a simple yet powerful 2D physics system
* inspired by Towerfall's physics mechanics. Supports dynamic actors, static solids, and trigger sensors.
*
* @example
* ```typescript
* // Initialize the physics system
* const physics = this.app.getPlugin('crunch-physics') as ICrunchPhysicsPlugin;
*
* const physics = await this.physics.initialize({
* gravity: 900,
* debug: true,
* gridSize: 32
* });
*
* // Create a player character
* const playerSprite = this.add.sprite({asset:Texture.WHITE, width: 32, height: 64});
*
* const player = physics.createActor({
* type: 'Player',
* position: [100, 100],
* size: [32, 64],
* view: playerSprite
* });
*
* // Create a platform
* const platformSprite = this.add.sprite({asset:Texture.WHITE, width: 800, height: 32, tint: 0x00FF00});
* const platform = physics.createSolid({
* type: 'Platform',
* position: [0, 500],
* size: [800, 32],
* view: platformSprite
* });
*
* // Create a coin pickup sensor
* const coinSprite = this.add.sprite({asset:Texture.WHITE, width: 32, height: 32, tint: 0x00FF00});
* const coin = physics.createSensor({
* type: 'Coin',
* position: [400, 400],
* size: [32, 32],
* view: coinSprite
* });
* ```
*/
export interface ICrunchPhysicsPlugin extends IPlugin<CrunchPhysicsOptions> {
system: System;
container: PIXIContainer;
enabled: boolean;
/**
* Initializes the physics system with the specified options.
*/
initialize(options?: Partial<CrunchPhysicsOptions>, app?: IApplication): Promise<void>;
/**
* Sets a custom collision resolver function that will be called when collisions occur.
*
* @param resolver - Function to handle collisions
*
* @example
* ```typescript
* physics.setCollisionResolver((collisions) => {
* collisions.forEach(collision => {
* if (collision.actor.type === 'Player' && collision.solid.type === 'Spike') {
* player.damage(10);
* }
* });
* });
* ```
*/
setCollisionResolver(resolver: (collisions: Collision[]) => void): void;
/**
* Sets a custom resolver for actor-to-actor collisions.
*
* @param resolver - Function to handle actor-to-actor collisions
*
* @example
* ```typescript
* physics.setActorCollisionResolver((collisions) => {
* collisions.forEach(collision => {
* if (collision.actor1.type === 'Player' && collision.actor2.type === 'Enemy') {
* player.takeDamage(10);
* }
* });
* });
* ```
*/
setActorCollisionResolver(resolver: (collisions: ActorCollision[]) => void): void;
/**
* Enables or disables actor-to-actor collision detection.
*
* @param enabled - Whether to enable actor-to-actor collisions
*
* @example
* ```typescript
* // Enable actor-to-actor collisions
* physics.setActorCollisionsEnabled(true);
*
* // Disable actor-to-actor collisions for performance
* physics.setActorCollisionsEnabled(false);
* ```
*/
setActorCollisionsEnabled(enabled: boolean): void;
/**
* Creates a generic physics entity based on the provided configuration.
* Use this when you need to create an entity without knowing its specific type at compile time.
*
* @param config - Configuration for the physics entity
* @returns The created physics entity
*
* @example
* ```typescript
* const entityConfig = {
* type: 'Platform',
* position: [100, 100],
* size: [200, 32],
* view: sprite
* };
* const entity = physics.createEntity(entityConfig);
* ```
*/
createEntity(config: PhysicsEntityConfig): Actor | Solid | Sensor | Group;
/**
* Adds an existing physics entity to the system.
* Useful when you want to manage entity creation yourself.
*
* @param entity - The physics entity to add
* @returns The added entity
*
* @example
* ```typescript
* class CustomActor extends Actor {
* constructor() {
* super({ type: 'Custom', position: [0, 0], size: [32, 32] });
* }
* }
*
* const customActor = new CustomActor();
* physics.addEntity(customActor);
* ```
*/
addEntity(entity: Actor | Solid | Sensor | Group): Actor | Solid | Sensor | Group;
/**
* Creates a dynamic physics actor that can move and collide with other entities.
* Actors are typically used for players, enemies, or any moving game objects.
*
* @param config - Configuration for the actor
* @returns The created actor
*
* @example
* ```typescript
* // Create a player character
* const player = physics.createActor({
* type: 'Player',
* position: [100, 100],
* size: [32, 64],
* view: playerSprite
* });
*
* // Update player in game loop
* player.velocity.x = 300; // Move right
* player.velocity.y = -600; // Jump
* ```
*/
createActor(config: PhysicsEntityConfig): Actor;
/**
* Creates a static solid object that other entities can collide with.
* Solids are typically used for platforms, walls, and other immovable objects.
*
* @param config - Configuration for the solid
* @returns The created solid
*
* @example
* ```typescript
* // Create a static platform
* const platform = physics.createSolid({
* type: 'Platform',
* position: [0, 500],
* size: [800, 32],
* view: platformSprite
* });
*
* // Create a moving platform
* const movingPlatform = physics.createSolid({
* type: 'Platform',
* position: [100, 300],
* size: [200, 32],
* view: platformSprite
* });
*
* // Update platform position
* gsap.to(movingPlatform, {
* x: 500,
* duration: 2,
* yoyo: true,
* repeat: -1
* });
* ```
*/
createSolid(config: PhysicsEntityConfig): Solid;
/**
* Creates a sensor zone that can detect overlaps with other entities.
* Sensors are typically used for triggers, collectibles, or detection zones.
*
* @param config - Configuration for the sensor
* @returns The created sensor
*
* @example
* ```typescript
* // Create a coin pickup
* const coin = physics.createSensor({
* type: 'Coin',
* position: [400, 300],
* size: [32, 32],
* view: coinSprite
* });
*
* // Handle coin collection
* coin.onActorEnter = (actor) => {
* if (actor.type === 'Player') {
* increaseScore(10);
* physics.removeSensor(coin);
* }
* };
* ```
*/
createSensor(config: PhysicsEntityConfig): Sensor;
createGroup(config: PhysicsEntityConfig): Group;
addActor(actor: Actor): Actor;
addSolid(solid: Solid): Solid;
addSensor(sensor: Sensor): Sensor;
addGroup(group: Group): Group;
/**
* Removes an actor from the physics system.
*
* @param actor - The actor to remove
*
* @example
* ```typescript
* // Remove player when they die
* function killPlayer(player: Actor) {
* playDeathAnimation();
* physics.removeActor(player);
* }
* ```
*/
removeActor(actor: Actor): void;
/**
* Removes a solid from the physics system.
*
* @param solid - The solid to remove
*
* @example
* ```typescript
* // Remove a platform when it's destroyed
* function destroyPlatform(platform: Solid) {
* playBreakAnimation();
* physics.removeSolid(platform);
* }
* ```
*/
removeSolid(solid: Solid): void;
/**
* Removes a sensor from the physics system.
*
* @param sensor - The sensor to remove
*
* @example
* ```typescript
* // Remove a coin when it's collected
* function collectCoin(coin: Sensor) {
* playCollectSound();
* physics.removeSensor(coin);
* }
* ```
*/
removeSensor(sensor: Sensor): void;
/**
* Cleans up the physics system and removes all entities.
* Call this when transitioning between scenes or shutting down the game.
*
* @example
* ```typescript
* class GameScene extends Scene {
* destroy() {
* this.physics.destroy();
* super.destroy();
* }
* }
* ```
*/
destroy(): void;
/**
* Creates a custom collision layer.
*
* @param index Index from 0-15 representing which user bit to use (gets shifted to bits 16-31)
* @returns A unique collision layer value
*
* @example
* ```typescript
* // Create custom collision layers
* const WATER_LAYER = physics.createCollisionLayer(0);
* const LAVA_LAYER = physics.createCollisionLayer(1);
*
* // Use in entity creation
* const waterEntity = physics.createActor({
* type: 'Water',
* position: [100, 400],
* size: [800, 100],
* collisionLayer: WATER_LAYER,
* collisionMask: CollisionLayer.PLAYER | CollisionLayer.ENEMY
* });
* ```
*/
createCollisionLayer(index: number): number;
/**
* Creates a collision mask from multiple layers.
*
* @param layers Array of collision layers to combine
* @returns A combined collision mask
*
* @example
* ```typescript
* // Create a mask that collides with players, enemies and projectiles
* const mask = physics.createCollisionMask([
* CollisionLayer.PLAYER,
* CollisionLayer.ENEMY,
* CollisionLayer.PROJECTILE
* ]);
* ```
*/
createCollisionMask(...layers: number[]): number;
/**
* Registers a named collision layer for better intellisense support.
*
* @param name Name of the collision layer (used for intellisense)
* @param indexOrDescription Index or description of the layer
* @param description Optional description of the layer
* @returns The numeric value of the registered collision layer
*
* @example
* ```typescript
* // Register named collision layers
* const WATER = physics.registerCollisionLayer('WATER', 0, 'Water surfaces');
* const LAVA = physics.registerCollisionLayer('LAVA', 1, 'Lava surfaces that damage players');
*
* // Use in entity creation
* const waterEntity = physics.createActor({
* type: 'Water',
* position: [100, 400],
* size: [800, 100],
* collisionLayer: WATER,
* collisionMask: CollisionLayer.PLAYER | CollisionLayer.ENEMY
* });
* ```
*/
registerCollisionLayer(name: string, indexOrDescription?: number | string, description?: string): number;
/**
* Gets a registered collision layer by name.
*
* @param name Name of the collision layer
* @returns The numeric value of the registered collision layer or undefined if not found
*
* @example
* ```typescript
* // Get a registered collision layer
* const waterLayer = physics.getCollisionLayer('WATER');
* if (waterLayer !== undefined) {
* // Use the layer
* entity.setCollisionLayer(waterLayer);
* }
* ```
*/
getCollisionLayer(name: string): number | undefined;
/**
* Gets all registered collision layers.
*
* @returns Array of all registered collision layers
*
* @example
* ```typescript
* // Get all registered collision layers
* const layers = physics.getCollisionLayers();
* console.log(`Registered layers: ${layers.map(l => l.name).join(', ')}`);
* ```
*/
getCollisionLayers(): RegisteredCollisionLayer[];
/**
* Removes a registered collision layer.
*
* @param name Name of the collision layer to remove
* @returns True if the layer was removed, false if it didn't exist
*
* @example
* ```typescript
* // Remove a registered collision layer
* physics.removeCollisionLayer('WATER');
* ```
*/
removeCollisionLayer(name: string): boolean;
/**
* Clears all registered collision layers.
*
* @example
* ```typescript
* // Clear all registered collision layers
* physics.clearCollisionLayers();
* ```
*/
clearCollisionLayers(): void;
}
/**
* Implementation of the Crunch physics plugin.
* See {@link ICrunchPhysicsPlugin} for detailed API documentation and examples.
*/
export default class CrunchPhysicsPlugin extends Plugin<Application, CrunchPhysicsOptions> implements ICrunchPhysicsPlugin {
system: System;
container: PIXIContainer;
enabled: boolean;
private collisionResolver?;
private overlapResolver?;
private actorCollisionResolver?;
constructor();
private hello;
initialize(options?: Partial<CrunchPhysicsOptions>, app?: IApplication): Promise<void>;
setCollisionResolver(resolver: (collisions: Collision[]) => void): void;
setActorCollisionResolver(resolver: (collisions: ActorCollision[]) => void): void;
setActorCollisionsEnabled(enabled: boolean): void;
createEntity(config: PhysicsEntityConfig): Actor | Solid | Sensor | Group;
addEntity(entity: Actor | Solid | Sensor | Group): Actor | Solid | Sensor | Group;
createActor(config: PhysicsEntityConfig): Actor;
createSolid(config: PhysicsEntityConfig): Solid;
createSensor(config: PhysicsEntityConfig): Sensor;
createGroup(config: PhysicsEntityConfig): Group;
addActor(actor: Actor): Actor;
addSolid(solid: Solid): Solid;
addSensor(sensor: Sensor): Sensor;
addGroup(group: Group): Group;
removeActor(actor: Actor): void;
removeSolid(solid: Solid): void;
removeSensor(sensor: Sensor): void;
removeGroup(group: Group): void;
destroy(): void;
private update;
/**
* Creates a custom collision layer.
*
* @param index Index from 0-15 representing which user bit to use (gets shifted to bits 16-31)
* @returns A unique collision layer value
*/
createCollisionLayer(index: number): number;
/**
* Creates a collision mask from multiple layers.
*
* @param layers Array of collision layers to combine
* @returns A combined collision mask
*/
createCollisionMask(...layers: number[]): number;
/**
* Registers a named collision layer for better intellisense support.
*
* @param name Name of the collision layer (used for intellisense)
* @param indexOrDescription Index or description of the layer
* @param description Optional description of the layer
* @returns The numeric value of the registered collision layer
*/
registerCollisionLayer(name: string, indexOrDescription?: number | string, description?: string): number;
/**
* Gets a registered collision layer by name.
*
* @param name Name of the collision layer
* @returns The numeric value of the registered collision layer or undefined if not found
*/
getCollisionLayer(name: string): number | undefined;
/**
* Gets all registered collision layers.
*
* @returns Array of all registered collision layers
*/
getCollisionLayers(): RegisteredCollisionLayer[];
/**
* Removes a registered collision layer.
*
* @param name Name of the collision layer to remove
* @returns True if the layer was removed, false if it didn't exist
*/
removeCollisionLayer(name: string): boolean;
/**
* Clears all registered collision layers.
*/
clearCollisionLayers(): void;
/**
* Checks if two AABB rectangles overlap.
*
* @param a - The first AABB rectangle
* @param b - The second AABB rectangle
* @returns True if the rectangles overlap, false otherwise
*/
aabbOverlap(a: AABBLike, b: AABBLike): boolean;
}
//# sourceMappingURL=CrunchPhysicsPlugin.d.ts.map