@curiousmedia/createjs-scene-container
Version:
A scene manager for CreateJS
223 lines (177 loc) • 4.85 kB
JavaScript
const _scenes = {};
const _transitions = {};
let instance;
export default class SceneContainer extends createjs.Container
{
constructor()
{
super();
if ( instance ) throw new Error( "Only one instance of SceneContainer allowed" );
this.anchorX = 0.5;
this.anchorY = 0.5;
this._last = null;
this.lastID = "";
this.current = null;
this.currentID = "";
}
static get scenes()
{
return _scenes;
}
static get currentScene()
{
return SceneContainer.getCurrentScene();
}
static getInstance()
{
if ( !instance ) instance = new SceneContainer();
return instance;
}
static getCurrentScene()
{
return instance && instance.current;
}
static registerScene( sceneId, SceneClass )
{
// console.log( "Registering Scene: ", sceneId );
_scenes[sceneId] = { id: sceneId, sceneClass: SceneClass };
}
static registerTransition( transitionId, TransitionClass )
{
// console.log( "Registering Transition/Loader Scene: ", transitionId );
_transitions[transitionId] = { id: transitionId, instance: new TransitionClass( transitionId ) };
}
static registerDefaultTransition( TransitionClass )
{
this.registerTransition( "default", TransitionClass);
}
static getSceneDefinition( sceneId )
{
return _scenes[sceneId] || false;
}
static getTransitionDefinition( transitionId )
{
return _transitions[transitionId] || false;
}
static gotoScene( sceneId, options, transitionId, transitionOptions )
{
instance.gotoScene( sceneId, options, transitionId, transitionOptions );
}
gotoScene( sceneId, options, transitionId = "default", transitionOptions = {} )
{
const current = this.current;
const nextSceneDef = SceneContainer.getSceneDefinition( sceneId );
if ( !nextSceneDef )
{
throw new Error( "No Scene with id: " + sceneId );
}
_log(" ------ ");
_log("Starting Scene Change");
// Start promise chain
let promiseChain = Promise.resolve();
let transition;
// If there's a current scene
if ( current )
{
_log("Removing Current Scene");
promiseChain = promiseChain.then( () => current.end() ); // end it
promiseChain = promiseChain.then( () => current.animateOut() ); // animate out
// Transition
const transitionDef = SceneContainer.getTransitionDefinition( transitionId );
transition = transitionDef.instance;
if ( transition )
{
_log("Adding Transition");
promiseChain = promiseChain.then( () => this.addTransition( transition ) );
promiseChain = promiseChain.then( () => transition.setup( transitionOptions ) );
promiseChain = promiseChain.then( () => transition.animateIn() );
promiseChain = promiseChain.then( () => transition.loadAssets() );
}
}
_log("Next Scene: " + nextSceneDef.id);
// Start prepping next scene
const NextSceneClass = nextSceneDef.sceneClass;
_log("Loading Next Scene");
promiseChain = promiseChain.then( () => NextSceneClass.preload() );
_log("Creating Next Scene");
// Now make the next scene
let next;
promiseChain = promiseChain.then( () =>
{
next = new NextSceneClass( nextSceneDef.id, options );
return Promise.resolve();
} );
// swap scenes
promiseChain = promiseChain.then( () => this.swapScenes( current, next ) );
promiseChain = promiseChain.then( () => next.setup( options ) );
promiseChain = promiseChain.then( () => next.reset() );
if ( transition )
{
_log("Removing Transition");
promiseChain = promiseChain.then( () => transition.animateOut() );
promiseChain = promiseChain.then( () =>
{
this.removeChild( transition );
return Promise.resolve();
} );
}
promiseChain = promiseChain.then( () => next.animateIn() );
promiseChain.then( () => next.start() );
}
setScreenAnchors( anchorX = 0.5, anchorY = 0.5 )
{
this.anchorX = anchorX;
this.anchorY = anchorY;
}
swapScenes( current, next )
{
if ( current )
{
current.destroy();
this.removeChild( current );
}
this.addChildAt( next, 0 );
this.current = next;
const event = new Event( "change" );
event.current = this.current;
event.previous = current;
this.dispatchEvent( event );
return Promise.resolve();
}
addTransition( loaderOfTransition )
{
this.addChild( loaderOfTransition );
return Promise.resolve();
}
transitOut()
{
return this.transitionOverlay.transitOut();
}
transitIn()
{
return this.transitionOverlay.transitIn();
}
_tick( evt )
{
super._tick( evt );
const stage = this.stage;
if ( stage && this.parent === stage )
{
this.x = Math.floor( stage.canvas.width * this.anchorX );
this.y = Math.floor( stage.canvas.height * this.anchorY );
}
if ( this.current )
{
this.current.update( evt.delta / 1000 );
}
}
}
function _log( message )
{
const promise = new Promise( resolve =>
{
console.log(message);
resolve();
});
return promise;
}