import { Debug } from "./debug" ; import { Emitter , EmitterConstructionOptions } from "./particles/emitter" ; import { Renderer } from "./particles/renderer" ; /**
 * Represents a scene that contains emitters and their particles.
 *
 * Scenes are responsible for spawning and updating emitters, and
 * removing them once they are done.
 *
 * Scenes are not explicitely present in the DOM as an element, only
 * the contained particles are.
 */ export class Scene { /**
     * The emitters currently present in the scene.
     */ public emitters : Emitter [ ] = [ ] ; /**
     * The debug instance associated with the scene.
     */ public readonly debug = new Debug ( this ) ; /**
     * The renderer associated with the scene.
     */ public readonly renderer = new Renderer ( ) ; /**
     * The ID of the currently scheduled tick.
     */ private scheduledTickId ? : number = undefined ; initialValue see https private lastTickTimestamp = performance . now ( ) ; /**
     * Initializes a new scene and starts the ticking job.
     */ constructor ( ) { this . tick = this . tick . bind ( this ) ; this . scheduleTick ( ) ; } /**
     * Creates and returns a new, default emitter object.
     */ public createEmitter ( options ? ) { const emitter = new Emitter ( options ) ; this . emitters . push ( emitter ) ; return emitter ; } returns public clearEmitters ( ) { return this . emitters . splice ( 0 ) . length ; } returns public clearParticles ( ) { return this . emitters . reduce ( ( sum , emitter ) => sum + emitter . clearParticles ( ) , 0 ) ; } /**
     * Schedules a tick in the scene.
     */ public scheduleTick ( ) { this . scheduledTickId = window . requestAnimationFrame ( this . tick ) ; } /**
     * Cancels a pending tick operation.
     */ public cancelTick ( ) { window . cancelAnimationFrame ( this . scheduledTickId ) ; } remarks param timestamp private tick ( timestamp ) { const delta = ( timestamp - this . lastTickTimestamp ) / 1000 ; try { for ( let i = 0 ; i < this . emitters . length ; i ++ ) { const emitter = this . emitters [ i ] ; emitter . tick ( delta ) ; if ( emitter . isExpired && emitter . canRemove ) { this . emitters . splice ( i -- , 1 ) ; } } } catch ( error ) { console . error ( `An error occurred while updating the scene's emitters:\n"${ error }"` ) ; } try { this . renderer . begin ( ) ; for ( const emitter of this . emitters ) { for ( const particle of emitter . particles ) { this . renderer . renderParticle ( particle , emitter ) ; } } this . renderer . end ( ) ; } catch ( error ) { console . error ( `An error occurred while rendering the scene's particles:\n"${ error }"` ) ; } this . debug . tick ( delta ) ; this . lastTickTimestamp = timestamp ; this . scheduleTick ( ) ; } }