API Docs for: 1.4.0
Show:

File: src\core\State.ts

/**
* 
* @module Kiwi
* 
*/

module Kiwi {

	/**
	* A State in Kiwi.JS is the main class that developers use when wanting to create a Game. 
	* States in Kiwi are used keep different sections of a game seperated. So a single game maybe comprised of many different States. 
	* Such as one for the menu, in-game, leaderboard, e.t.c.
	* There can only ever be a single State active at a given time.   
	* 
	* @class State
	* @namespace Kiwi
	* @extends Kiwi.Group
	* @constructor
	* @param name {String} Name of this State. Should be unique to differentiate itself from other States.
	* @return {Kiwi.State} 
	*/
	export class State extends Group {

		constructor(name: string) {
			super(null, name);
			
			this.config = new Kiwi.StateConfig(this, name);
			this.components = new Kiwi.ComponentManager(Kiwi.STATE, this);
			this.transform.parent = null;
			this._trackingList = [];
		}

		/**
		* Returns the type of object this state is.
		* @method objType
		* @return {String} "State"
		* @public
		*/
		public objType() {
			return "State";
		}

		/**
		* Returns the type of child this is. 
		* @method childType
		* @return {Number} Kiwi.GROUP
		* @public
		*/
		public childType() {
			return Kiwi.GROUP;
		}

		/**
		* The configuration object for this State.
		* @property config
		* @type Kiwi.StateConfig
		* @public
		*/
		public config: Kiwi.StateConfig;

		/**
		* A reference to the Kiwi.Game that this State belongs to.
		* @property game
		* @type Kiwi.Game
		* @public
		*/
		public game: Kiwi.Game = null;

		/**
		* The library that this state use's for the loading of textures.
		* @property textureLibrary
		* @type Kiwi.Textures.TextureLibrary
		* @public
		*/
		public textureLibrary: Kiwi.Textures.TextureLibrary;

		/**
		* The library that this state use's for the loading of audio.
		* @property audioLibrary
		* @type Kiwi.Sound.AudioLibrary
		* @public
		*/
		public audioLibrary: Kiwi.Sound.AudioLibrary;

		/**
		* The library that this state use's for the loading of data.
		* @property dataLibrary
		* @type Kiwi.Files.DataLibrary
		* @public
		*/
		public dataLibrary: Kiwi.Files.DataLibrary;

		/**
		* Holds all of the textures that are avaiable to be accessed once this state has been loaded.
		* E.g. If you loaded a image and named it 'flower', once everything has loaded you can then access the flower image by saying this.textures.flower
		* @property textures
		* @type Object
		* @public
		*/
		public textures;

		/**
		* Holds all of the audio that are avaiable to be accessed once this state has been loaded.
		* E.g. If you loaded a piece of audio and named it 'lazerz', once everything has loaded you can then access the lazers (pew pew) by saying this.audio.lazerz
		* @property audio
		* @type Object
		* @public
		*/
		public audio;

		/**
		* Holds all of the data that are avaiable to be accessed once this state has been loaded.
		* E.g. If you loaded a piece of data and named it 'cookieLocation', once everything has loaded you can then access the cookies by saying this.data.cookieLocation
		* @property data
		* @type Object
		* @public
		*/
		public data;

		/**
		* This method is executed when this State is about to be switched too. This is the first method to be executed, and happens before the Init method.
		* Is called each time a State is switched to.
		* @method boot
		* @public
		*/
		public boot() {

			this.textureLibrary = new Kiwi.Textures.TextureLibrary(this.game);
			this.textures = this.textureLibrary.textures;
			this.audioLibrary = new Kiwi.Sound.AudioLibrary(this.game);
			this.audio = this.audioLibrary.audio;
			this.dataLibrary = new Kiwi.Files.DataLibrary(this.game);
			this.data = this.dataLibrary.data;
		}

		/*
		* Currently unused.
		*/
		public setType(value: number) {

			if (this.config.isInitialised === false) {
				this.config.type = value;
			}

		}


		/*
		*--------------
		* Methods that are to be Over-Ridden by Devs.
		*--------------
		*/


		/**
		* Gets executed when the state has been initalised and gets switched to for the first time.
		* This method only ever gets called once and it is before the preload method.
		* Can have parameters passed to it by the previous state that switched to it.
		* @method init
		* @param [values] { Any } 
		* @public
		*/
		public init(...paramsArr: any[]) { }

		/**
		* This method is where you would load of all the assets that are requried for this state or in the entire game.
		*
		* @method preload
		* @public
		*/
		public preload() { }

		/**
		* This method is progressively called whilst loading files and is executed each time a file has been loaded.
		* This can be used to create a 'progress' bar during the loading stage of a game.
		* @method loadProgress
		* @param percent {Number} The percent of files that have been loaded so far. This is a number from 0 - 1.
		* @param bytesLoaded {Number} The number of bytes that have been loaded so far.
		* @param file {Kiwi.Files.File} The last file to have been loaded.
		* @public
		*/
		public loadProgress(percent: number, bytesLoaded: number, file: Kiwi.Files.File) { }

		/**
		* Gets executed when the game is finished loading and it is about to 'create' the state. 
		* @method loadComplete
		* @public
		*/
		public loadComplete() { }

		/**
		* The game loop that gets executed while the game is loading. 
		* @method loadUpdate
		* @public
		*/
		public loadUpdate() {

			for (var i = 0; i < this.members.length; i++) { 
				if (this.members[i].active === true)
				{
					this.members[i].update();
				}
			}
		}

		/** 
		* Is executed once all of the assets have loaded and the game is ready to be 'created'.
		* @method create
		* @param [values]* {Any} 
		* @public
		*/
		public create(...paramsArr: any[]) { }

		/**
		* Is called every frame before the update loop. When overriding make sure you include a super call.
		* @method preUpdate
		* @public
		*/
		public preUpdate() {
			this.components.preUpdate();
		}

		/**
		* The update loop that is executed every frame while the game is 'playing'. When overriding make sure you include a super call too.
		* @method update
		* @public
		*/
		public update() {
			
			this.components.update();
			
			for (var i = 0; i < this.members.length; i++) {

				//Should the update loop be executed?
				if (this.members[i].active === true) {
					this.members[i].update();
				
				}
				
				//Does the child need to be destroyed?
				if (this.members[i].exists === false) {
					this.members[i].destroy( true );
				}
			}
		}

		/**
		* The post update loop is executed every frame after the update method. 
		* When overriding make sure you include a super call at the end of the method.
		* @method postUpdate
		* @public
		*/
		public postUpdate() {
			this.components.postUpdate();
		}

		/**
		* Called after all of the layers have rendered themselves, useful for debugging.
		* @method postRender
		* @public
		*/
		public postRender() { }

		/**
		* Called just before this State is going to be Shut Down and another one is going to be switched too. 
		* @method shutDown
		* @public
		*/
		public shutDown() { }


		/*
		*--------------
		* Loading Methods
		*--------------
		*/


		/**
		* Adds a new image file that is be loaded when the state gets up to the loading all of the assets.
		*
		* @method addImage
		* @param key {String} A key for this image so that you can access it when the loading has finished.
		* @param url {String} The location of the image.
		* @param [storeAsGlobal=true] {boolean} If the image should be deleted when switching to another state or if the other states should still be able to access this image.
		* @param [width] {Number} The width of the image. If not passed the width will be automatically calculated.
		* @param [height] {Number} The height of the image. If not passed the height will be automatically calculated.
		* @param [offsetX] {Number} The offset of the image when rendering on the x axis. 
		* @param [offsetY] {Number} The offset of the image when rendering on the y axis.
		* @public
		*/
		public addImage(key: string, url: string, storeAsGlobal: boolean = true, width?: number, height?: number, offsetX?: number, offsetY?: number) {
			return this.game.loader.addImage(key, url, width, height, offsetX, offsetY, storeAsGlobal);
		}

		/**
		* Adds a new spritesheet image file that is be loaded when the state gets up to the loading all of the assets.
		*
		* @method addSpriteSheet
		* @param key {String} A key for this image so that you can access it when the loading has finished.
		* @param url {String} The location of the image.
		* @param frameWidth {Number} The width of a single frame in the spritesheet
		* @param frameHeight {Number} The height of a single frame in the spritesheet
		* @param [storeAsGlobal=true] {boolean} If the image should be deleted when switching to another state or if the other states should still be able to access this image.
		* @param [numCells] {Number} The number of cells/frames that are in the spritesheet. If not specified will calculate this based of the width/height of the image.
		* @param [rows] {Number} The number of cells that are in a row. If not specified will calculate this based of the width/height of the image. 
		* @param [cols] {Number} The number of cells that are in a column. If not specified will calculate this based of the width/height of the image.
		* @param [sheetOffsetX=0] {Number} The offset of the whole spritesheet on the x axis.
		* @param [sheetOffsetY=0] {Number} The offset of the whole spritesheet on the y axis.
		* @param [cellOffsetX=0] {Number} The spacing between cells on the x axis.
		* @param [cellOffsetY=0] {Number} The spacing between cells on the y axis.
		* @public 
		*/
		public addSpriteSheet(key: string, url: string, frameWidth: number, frameHeight: number, storeAsGlobal: boolean = true, numCells?: number, rows?: number, cols?: number, sheetOffsetX?: number, sheetOffsetY?: number, cellOffsetX?: number, cellOffsetY?: number) {

			return this.game.loader.addSpriteSheet(key, url, frameWidth, frameHeight, numCells, rows, cols, sheetOffsetX, sheetOffsetY, cellOffsetX, cellOffsetY, storeAsGlobal);
		}

		/**
		* Adds a new texture atlas that is to be loaded when the states gets up to the stage of loading the assets.
		*
		* @method addTextureAtlas
		* @param key {String} A key for this image so that you can access it when the loading has finished.
		* @param imageURL {String} The location of the image.
		* @param [jsonID] {String} The id for the json file that is to be loaded. So that you can access it outside of the texture atlas.
		* @param [jsonURL] {String} The location of the json file you have loaded.
		* @param [storeAsGlobal=true] {boolean} If the image should be delete when switching to another state or if the other states should still be able to access this image.
		* @public
		*/
		public addTextureAtlas(key: string, imageURL: string, jsonID?: string, jsonURL?: string, storeAsGlobal: boolean = true) {

			return this.game.loader.addTextureAtlas(key, imageURL, jsonID, jsonURL, storeAsGlobal);

		}

		/**
		* Adds a json file that is to be loaded when the state gets up to the stage of loading the assets.
		* 
		* @method addJSON
		* @param key {string} A key for this json so that you can access it when the loading has finished
		* @param url {string} The location of the JSON file.
		* @param [storeAsGlobal=true] {boolean} If the json should be deleted when switching to another state or if the other states should still be able to access this json.
		* @public
		*/
		public addJSON(key: string, url: string, storeAsGlobal: boolean = true) {

			return this.game.loader.addJSON(key, url, storeAsGlobal);
		}

		/**
		* Adds a new audio file that is to be loaded when the state gets up to the stage of loading the assets.
		* 
		* @method addAudio
		* @param key {string} A key for this audio so that you can access it when the loading has finished
		* @param url {string} The location of the audio file. You can pass a array of urls, in which case the first supported filetype will be used.
		* @param [storeAsGlobal=true] {boolean} If the audio should be deleted when switching to another state or if the other states should still be able to access this audio.
		*/
		public addAudio(key: string, url: any, storeAsGlobal: boolean = true) {

			return this.game.loader.addAudio(key, url, storeAsGlobal);

		}


		/*
		*----------------
		* Garbage Collection 
		*----------------
		*/


		/**
		* Contains a reference to all of the Objects that have ever been created for this state. Generally Kiwi.Entities or Kiwi.Groups.
		* Useful for keeping track of sprites that are not used any more and need to be destroyed.
		* @property trackingList
		* @type Array
		* @private
		*/
		private _trackingList: Kiwi.IChild[];

		/**
		* Adds a new Objects to the tracking list. 
		* This is an INTERNAL Kiwi method and DEVS shouldn't need to worry about it.
		* @method addToTrackingList
		* @param child {Object} The Object which you are adding to the tracking list.
		* @public
		*/
		public addToTrackingList(child: Kiwi.IChild) {
			//check to see that its not already in the tracking list.
			if (this._trackingList.indexOf(child) !== -1) return;
			//add to the list
			this._trackingList.push(child);
		}

		/**
		* Removes a Object from the tracking list. This should only need to happen when a child is being destroyed.
		* This is an INTERNAL Kiwi method and DEVS shouldn't really need to worry about it.
		* @method removeFromTrackingList
		* @param child {Object} The object which is being removed from the tracking list. 
		* @public
		*/
		public removeFromTrackingList(child:Kiwi.IChild) {
			//check to see that it is in the tracking list.
			var n = this._trackingList.indexOf(child);
			if (n > -1) {
				this._trackingList.splice(n, 1);
			} 
		}

		/**
		* Destroys all of Objects in the tracking list that are not currently on stage. 
		* All that currently don't have this STATE as an ancestor.
		* Returns the number of Objects removed.  
		* @method destroyUnused
		* @return {Number} The amount of objects removed.
		* @public
		*/
		public destroyUnused():number {

			var d = 0; 
			for (var i = 0; i < this._trackingList.length; i++) {
				if (this.containsAncestor(this._trackingList[i], this) === false) {
					this._trackingList[i].destroy();
					this._trackingList.splice(i, 1);
					i--;
					d++;
				}
			}

			return d;
		}

		/**
		* Used to mark all Entities that have been created for deletion, regardless of it they are on the stage or not.
		* @method destroy
		* @param [deleteAll=true] If all of the Objects ever created should have the destroy method executed also.
		* @public
		*/
		public destroy(deleteAll: boolean=true) {

			if (deleteAll == true) {

				//destroy all of the tracking list
				while( this._trackingList.length > 0 ) {

					//If the item is a group then we don't want it to destroy it's children, as this method will do that eventually anyway.
					this._trackingList[0].destroy( true , false ); 
				}
				this._trackingList = [];
				
                //destroy all of the groups members. Usually they would be apart of the trackingList 
                while (this.members.length > 0) {

                    //If the item is a group then we don't want it to destroy it's children, as this method will do that eventually anyway.
                    this.members[0].destroy(true, false);
                }
				this.members = [];    

			}

		}

		/**
		* Recursively goes through a child given and runs the destroy method on all that are passed.
		* @method _destroyChildren
		* @param child {Object}
		* @private
		*/
		private _destroyChildren(child: any) {
			if (child.childType() == Kiwi.GROUP) {
				for (var i = 0; i < child.members.length; i++) {
					this._destroyChildren(child.members[i]);
				}
			}
			child.destroy( true );
		}

	}

}