import { ControllerManager } from "./input/ControllerManager" ; import { Game } from "./Game" ; import { Keyboard } from "./input/Keyboard" ; import { Scenes } from "./Scenes" ; import { Transition } from "./Transition" ; import { RootNode , UpdateRootNode , DrawRootNode } from "./scene/RootNode" ; import { SceneNode } from "./scene/SceneNode" ; param T param A export type SceneConstructor < T extends Game , A = void > = new ( game ) => Scene < T , A > ; param T param A export abstract class Scene < T extends Game , A = void > { public zIndex : number = 0 ; public currentTransition : Transition | null = null ; public inTransition : Transition | null = null ; public outTransition : Transition | null = null ; public readonly rootNode : RootNode < T > ; private updateRootNode ! : UpdateRootNode ; private drawRootNode ! : DrawRootNode ; private usedLayers : number = 0 ; private hiddenLayers : number = 0 ; private backgroundStyle : string | null = null ; public constructor ( public readonly game ) { this . rootNode = new RootNode ( this , ( update , draw ) => { this . updateRootNode = update ; this . drawRootNode = draw ; } ) ; this . rootNode . resizeTo ( this . game . width , this . game . height ) ; } public get keyboard ( ) : Keyboard { return this . game . keyboard ; } public get input ( ) : ControllerManager { return ControllerManager . getInstance ( ) ; } public get scenes ( ) : Scenes < T > { return this . game . scenes ; } param layer public showLayer ( layer ) { this . hiddenLayers &= ~ ( 1 << layer ) ; return this ; } param layer public hideLayer ( layer ) { this . hiddenLayers |= 1 << layer ; return this ; } param layer return public isLayerHidden ( layer ) { return ( this . hiddenLayers & ( 1 << layer ) ) !== 0 ; } param layer return public isLayerShown ( layer ) { return ( this . hiddenLayers & ( 1 << layer ) ) === 0 ; } param id return public getNodeById ( id ) { return this . rootNode . getDescendantById ( id ) ; } return public getBackgroundStyle ( ) { return this . backgroundStyle ; } param backgroundStyle public setBackgroundStyle ( backgroundStyle ) { this . backgroundStyle = backgroundStyle ; return this ; } return public isActive ( ) { return this . scenes . activeScene === this ; } param args public setup ( args ) { } /**
     * Called when the scene becomes the top scene on the stack and after the on-stage transition is complete.
     */ public activate ( ) { } /**
     * Called when the scene is no longer the top scene on the stack and before the off-stage transition begins.
     */ public deactivate ( ) { } /**
     * Called when the scene is popped from the scene stack, after any transitions are complete.
     */ public cleanup ( ) { } /**
     * Updates the scene. Scenes can overwrite this method to do its own drawing but when you are going to use the
     * scene graph then make sure to call the super method in your overwritten method or the scene graph will not be
     * updated.
     */ public update ( dt ) { this . usedLayers = this . updateRootNode ( dt ) ; } param ctx param width param height public draw ( ctx , width , height ) { if ( this . backgroundStyle != null ) { ctx . save ( ) ; ctx . fillStyle = this . backgroundStyle ; ctx . fillRect ( 0 , 0 , width , height ) ; } let layer = 1 ; let usedLayers = this . usedLayers & ~ this . hiddenLayers ; while ( usedLayers !== 0 ) { if ( ( usedLayers & 1 ) === 1 ) { this . drawRootNode ( ctx , layer , width , height ) ; } usedLayers >>>= 1 ; layer <<= 1 ; } } }