API Docs for: 0.1.0
Show:

File: src/zerk/class/game/engine.js

/**
 * The game engine main class
 * 
 * @class zerk.game.engine
 * @extends zerk.observable
 * @module zerk
 */
zerk.define({
	
	name: 'zerk.game.engine',
	extend: 'zerk.observable',
	require: [
		'zerk.game.engine.registry',
		'zerk.game.engine.helper',
		'zerk.game.engine.debug',
		'zerk.game.engine.dom',
		'zerk.game.engine.control',
		'zerk.game.engine.viewport',
		'zerk.game.engine.physics',
		'zerk.game.engine.world',
		'zerk.game.engine.entity'
	]
	
},{
	
	/**
	 * Game engine registry
	 * 
	 * @property registry
	 * @type zerk.game.engine.registry
	 */
	registry: null,
	
	/**
	 * Global helpers
	 * 
	 * @property helper
	 * @type zerk.game.engine.helper
	 */
	helper: null,
	
	/**
	 * Debugger
	 * 
	 * @property debug
	 * @type zerk.game.engine.debug
	 */
	debug: null,
	
	/**
	 * DOM interface
	 * 
	 * @property dom
	 * @type zerk.game.engine.dom
	 */
	dom: null,
	
	/**
	 * Human input controls
	 * 
	 * @property control
	 * @type zerk.game.engine.control
	 */
	control: null,
	
	/**
	 * Grafical presentation
	 * 
	 * @property viewport
	 * @type zerk.game.engine.viewport
	 */
	viewport: null,
	
	/**
	 * Physics simulation
	 * 
	 * @property physics
	 * @type zerk.game.engine.physics
	 */
	physics: null,
	
	/**
	 * Back reference to the game class
	 * 
	 * @property game
	 * @type zerk.game
	 */
	game: null,
	
	/**
	 * World register
	 * 
	 * @property world
	 * @type zerk.game.engine.world
	 */
	world: null,
	
	/**
	 * Engine configuration
	 * 
	 * @property _config
	 * @type Null|Object
	 * @protected
	 */
	_config: null,
	
	/**
	 * Total world runtime
	 * 
	 * @property _time
	 * @type Integer
	 * @protected
	 */
	_time: 0,
		
	/**
	 * World timer interval
	 * 
	 * @property _worldInterval
	 * @type Integer
	 * @protected
	 */
	_worldInterval: 1000/60,
	
	/**
	 * World timer
	 * 
	 * @property _timer
	 * @type Null|Timer
	 * @protected
	 */
	_timer: null,
	
	/**
	 * Indicates that the engine is running
	 * 
	 * @property _running
	 * @type Boolean
	 * @protected
	 */
	_running: false,
	
	/**
	 * Indicates that the world is unloading
	 * 
	 * @property _unloadingWorld
	 * @type Boolean
	 * @protected
	 */
	_unloadingWorld: false,
	
	/**
	 * Class constructor
	 * 
	 * @method init
	 * @param {Object} config Game configuration
	 */
	init: function(game,config) {
		
		zerk.parent('zerk.game.engine').init.apply(
			this,
			arguments
		);
		
		this.game=game;
		
		this.registry=zerk.create(
			'zerk.game.engine.registry',
			this,
			config // Feed up the registry with the initial user config object
		);
		
		this._config={
			/*
			 * Mode setting
			 * 
			 * Possible values are:
			 *    default
			 *    debug
			 *    benchmark
			 */
			mode: 'default'
		};
		
		this._config=this.registry.register('engine',this._config);
		
		this.helper=zerk.create(
			'zerk.game.engine.helper',
			this
		);
		
		this.debug=zerk.create(
			'zerk.game.engine.debug',
			this
		);
		
		this.dom=zerk.create(
			'zerk.game.engine.dom',
			this
		);
		
		this.control=zerk.create(
			'zerk.game.engine.control',
			this
		);
		
		this.viewport=zerk.create(
			'zerk.game.engine.viewport',
			this
		);
		
		this.physics=zerk.create(
			'zerk.game.engine.physics',
			this
		);
		
		var me=this;
		
		window.onerror=function() {
			
			me.stop();
			
		};
		
		this._log('Init');
		
	},
	
	/**
	 * Start game engine
	 * 
	 * @method start
	 */
	start: function() {
		
		var me=this;
		
		this.viewport.start();
		
		this._running=true;
		
		this._log('Game started');
		
		this._tick(); // Run the first tick
		
		this._timer=window.setInterval(
			function() {
				
				me._tick();
				
			},
			this._worldInterval
		);
		
	},
	
	/**
	 * Stop game engine
	 * 
	 * @method stop
	 */
	stop: function() {
		
		if (!this._running) return;
		
		this.world.clear();
		
		this.viewport.stop();
		
		this._running=false;
		
		window.clearInterval(this._timer);
		
		this._log('Game stopped (Time '+this._time+')');
		
	},
	
	/**
	 * Pause game engine
	 * 
	 * @method pause
	 */
	pause: function() {
		
		window.clearInterval(this._timer);
		
		this._running=false;
		
		this._log('Game paused (Time '+this._time+')');
		
	},
	
	/**
	 * Loads a world
	 * 
	 * @method loadWorld
	 * @param {String} worldClass Class name of the world to be loaded
	 */
	loadWorld: function(worldClass) {
		
		this.world=zerk.create(worldClass,this);
		
	},
	
	/**
	 * Unloads the world
	 * 
	 * @method unloadWorld
	 */
	unloadWorld: function() {
		
		this.world.clear();
		
		this.world=null;
		
		this._unloadingWorld=true;
		
	},
	
	/**
	 * Save world state
	 * 
	 * @method saveWorld
	 * @return {String} World state as JSON string
	 */
	saveWorld: function() {
		
		var data={};
		
		data.worldConfig=this.world._config;
		data.entities=[];
		
		for (var i=0;i<this.world.entities.length;i++) {
			
			data.entities.push({
				name: this.world.entities[i].name,
				config: this.world.entities[i].config
			});
			
		}
		
		var json=JSON.stringify(data);
		
		return json;
		
	},
	
	/**
	 * Returns true if the game engine is running
	 * 
	 * @method isRunning
	 * @return {Boolean} True if the game engine is running
	 */
	isRunning: function() {
		
		return this._running;
		
	},
	
	/**
	 * Returns current world time
	 * 
	 * @method getTime
	 * @return {Integer} World time
	 */
	getTime: function() {
		
		return this._time;
		
	},
	
	/**
	 * Game engine tick
	 * 
	 * @method _tick
	 * @protected
	 */
	_tick: function() {
		
		this._time++;
		
		// Run physics tick
		this.physics.tick();
		
		// Process world unloading
		if (this._unloadingWorld) {
			
			this._unloadingWorld=false;
			
			/**
			 * Fires after the world is unloaded
			 * 
			 * @event worldunloaded 
			 */
			this.fireEvent('worldunloaded');
			
		}
		
		/**
		 * Fires every world simulation tick
		 * 
		 * @event tick 
		 */
		this.fireEvent('tick');
		
		if (this.world!=null) {
			
			for (var i=0;i<this.world.entities.length;i++) {
				
				// Sync entity physics data
				this.physics.syncEntityPhysics(
					this.world.entities[i]
				);
				
				// Process entity ticks
				this.world.entities[i].fireEvent('tick');
				
			}
		}
		
	},
	
	/**
	 * Local log method
	 * 
	 * @method _log
	 * @param {String} msg
	 * @protected
	 */
	_log: function(msg) {
		
		// Redirect to global log
		return this.debug.log(msg,this.debug.GROUP_ENGINE);
		
	}
	
});