UNPKG

@dill-pixel/plugin-crunch-physics

Version:

Crunch Physics

508 lines 16.5 kB
import { 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<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