API Docs for: 0.1.0
Show:

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

/**
 * Entity
 * 
 * All entities should inherit from here.
 * 
 * @class zerk.game.engine.entity
 * @extends zerk.observable
 * @module zerk
 */
zerk.define({
	
	name: 'zerk.game.engine.entity',
	extend: 'zerk.observable'
	
},{
	
	/**
	 * Fires when the entity gets spawned
	 * 
	 * @event spawn
	 * @return {Boolean} Return false to Cancel bubble
	 */
	
	/**
	 * Fires every world simulation tick
	 * 
	 * @event tick
	 * @return {Boolean} Return false to Cancel bubble
	 */
	
	/**
	 * Fires when two fixtures start colliding
	 * 
	 * @event contactbegin
	 * @param {zerk.game.engine.physics.fixture} sourceFixture Source fixture
	 * @param {zerk.game.engine.physics.fixture} targetFixture Target fixture
	 * @return {Boolean} Return false to Cancel bubble
	 */
	
	/**
	 * Fires when two fixtures stop colliding
	 * 
	 * @event contactend
	 * @param {zerk.game.engine.physics.fixture} sourceFixture Source fixture
	 * @param {zerk.game.engine.physics.fixture} targetFixture Target fixture
	 * @return {Boolean} Return false to Cancel bubble
	 */
	
	/**
	 * Fires before two fixtures start colliding
	 * 
	 * @event contactpostsolve
	 * @param {zerk.game.engine.physics.fixture} sourceFixture Source fixture
	 * @param {zerk.game.engine.physics.fixture} targetFixture Target fixture
	 * @param {Object} impulse
	 * @return {Boolean} Return false to Cancel bubble
	 */
	
	/**
	 * Name of the entity
	 * 
	 * @property name
	 * @type String
	 */
	name: '',
	
	/**
	 * Width of the entity
	 * 
	 * @property width
	 * @type Integer
	 */
	width: 0,
	
	/**
	 * Height of the entity
	 * 
	 * @property height
	 * @type Integer
	 */
	height: 0,
	
	/**
	 * Class constructor
	 * 
	 * @method init
	 * @param {zerk.game.engine} engine Game engine
	 * @param {Object} config Entity configuration
	 */
	init: function(engine) {
		
		zerk.parent('zerk.game.engine.entity').init.apply(
			this,
			arguments
		);
		
		this._engine=engine;
		
		this.joints=[];
		this.sprites={};
		
		// Extend default config with local config
		
		this.config={
			id: '',
			x: 0,
			y: 0,
			bodies: [
				
			]
		};
		
	},
	
	/**
	 * Destroys this entity and removes it from the world
	 * 
	 * @method destroy
	 */
	destroy: function() {
		
		this._engine.world.destroy(this);
		
	},
	
	/**
	 * Entity setup method
	 * 
	 * Entities should define their bodies and joints in this method
	 * 
	 * @method setup
	 */
	setup: function() {
		
		// Calculate initial positions relative to the origin body
		var x=0.0;
		var y=0.0;
		var angle=0;
		
		// Create positions for each body
		if (this.config.bodies.length==0) {
			
			for (var index in this.bodies) {
				
				if (this.bodies[index].origin) {
					
					x=this.config.x;
					y=this.config.y;
					
					if (this.config.angle) {
						
						angle=this.config.angle;
						
					} else {
						
						angle=this.bodies[index].angle;
						
					}
					
				} else {
					
					x=this.config.x+this.bodies[index].x;
					y=this.config.y+this.bodies[index].y;
					angle=this.bodies[index].angle;
					
				}
				
				this.config.bodies[this.bodies[index].key]={
					x: x,
					y: y,
					angle: angle
				};
				
			}
			
		}
		
		for (var index in this.bodies) {
			
			var extendedBody=zerk.create(
				'zerk.game.engine.physics.body'
			);
			
			zerk.apply(extendedBody,this.bodies[index]);
			
			extendedBody._entity=this;
			
			this.bodies[index]=extendedBody;
			
			var extendedFixture=null;
			
			for (var indexTwo in this.bodies[index].fixtures) {
				
				switch (this.bodies[index].fixtures[indexTwo].shape) {
					case 'box':
						extendedFixture=zerk.create(
							'zerk.game.engine.physics.fixture.rectangle',
							this.bodies[index]
						);
						break;
					case 'circle':
						extendedFixture=zerk.create(
							'zerk.game.engine.physics.fixture.circle',
							this.bodies[index]
						);
						break;
					case 'polygon':
						extendedFixture=zerk.create(
							'zerk.game.engine.physics.fixture.polygon',
							this.bodies[index]
						);
						break;
				}
				
				zerk.apply(
					extendedFixture,
					this.bodies[index].fixtures[indexTwo]
				);
				
				this.bodies[index].fixtures[indexTwo]=extendedFixture;
				
			}
			
		}
		
		var extendedJoint=null;
		
		for (var index in this.joints) {
			
			switch (this.joints[index].type) {
				case 'distance':
					extendedJoint=zerk.create(
						'zerk.game.engine.physics.joint.distance'
					);
					break;
				case 'revolute':
					extendedJoint=zerk.create(
						'zerk.game.engine.physics.joint.revolute'
					);
					break;
			}
			
			zerk.apply(extendedJoint,this.joints[index]);
			
			this.joints[index]=extendedJoint;
			
		}
		
		this._createMapBody();
		
	},
	
	/**
	 * Apply configuration object
	 * 
	 * @method applyConfig
	 * @param {Object} config
	 */
	applyConfig: function(config) {
		
		zerk.apply(
			this.config,
			config
		);
		
	},
	
	/**
	 * Returns a body by key
	 * 
	 * @method getBody
	 * @param {String} key Key of the body
	 * @return {zerk.game.engine.physics.body} Body instance
	 */
	getBody: function(key) {
		
		return this._mapBody[key];
		
	},
	
	/**
	 * Create a map to the physics handles of all bodies by their keys
	 * 
	 * @method _createMapBody
	 * @protected
	 */
	_createMapBody: function() {
		
		this._mapBody={};
		
		for (var index in this.bodies) {
			this._mapBody[this.bodies[index].key]=this.bodies[index];
		}
		
	},
	
	/**
	 * Applies an impulse to given body
	 * 
	 * @method _bodyApplyImpulse
	 * @param {String} bodyKey
	 * @param {Integer} degrees
	 * @param {Integer} power
	 * @protected
	 */
	_bodyApplyImpulse: function(bodyKey,degrees,power) {
		
		var physicsBody=this._mapBody[bodyKey].physicsHandle;
		
		physicsBody.ApplyImpulse(
			new this._engine.physics._b2Vec2(
				Math.cos(degrees*(Math.PI/180))*power,
				Math.sin(degrees*(Math.PI/180))*power
			),
			physicsBody.GetWorldCenter()
		);
		
	},
	
	/**
	 * Sets the linear velocity of given body
	 * 
	 * @method _setLinearVelocity
	 * @param {String} bodyKey
	 * @param {Integer} degrees
	 * @param {Integer} power
	 * @protected
	 */
	_setLinearVelocity: function(bodyKey,degrees,power) {
		
		var physicsBody=this._mapBody[bodyKey].physicsHandle;
		
		physicsBody.SetLinearVelocity(
			new this._engine.physics._b2Vec2(
				Math.cos(degrees*(Math.PI/180))*power,
				Math.sin(degrees*(Math.PI/180))*power
			)
		);
	
	},
	
	/**
	 * Sets the position of given body
	 * 
	 * @method _setBodyPosition
	 * @param {String} bodyKey
	 * @param {Object} position
	 * @protected
	 */
	_setBodyPosition: function(bodyKey,position) {
		
		var physicsBody=this._mapBody[bodyKey].physicsHandle;
		
		return physicsBody.SetPosition(position);
		
	},
	
	/**
	 * Sets whether given body is allowed to sleep
	 * 
	 * @method _setBodySleepingAllowed
	 * @param {String} bodyKey
	 * @param {Boolean} allowed
	 * @protected
	 */
	_setBodySleepingAllowed: function(bodyKey,allowed) {
		
		this.getBody(bodyKey).physicsHandle.SetSleepingAllowed(allowed);
		
	},
	
	/**
	 * Sets whether given body is moveable
	 * 
	 * @method _setBodyMoveable
	 * @param {String} bodyKey
	 * @param {Boolean} moveable
	 * @protected
	 */
	_setBodyMoveable: function(bodyKey,moveable) {
		
		var type=((moveable)
			? this._engine.physics._b2Body.b2_dynamicBody
			: this._engine.physics._b2Body.b2_staticBody);
		
		this.getBody(bodyKey).physicsHandle.SetType(
			type
		);
		
	},
	
	/**
	 * Sets given body to be kinematic
	 * 
	 * @method _setBodyKinematic
	 * @param {String} bodyKey
	 * @protected
	 */
	_setBodyKinematic: function(bodyKey) {
		
		this.getBody(bodyKey).physicsHandle.SetType(
			this._engine.physics._b2Body.b2_kinematicBody
		);
		
	},
	
	/**
	 * Returns position of given body
	 * 
	 * @method _getBodyPosition
	 * @param {String} bodyKey
	 * @return {Object} Position
	 * @protected
	 */
	_getBodyPosition: function(bodyKey) {
		
		return this.getBody(bodyKey).physicsHandle.GetPosition();
		
	},
	
	/**
	 * Returns the linear velocity of given body
	 * 
	 * @method _getBodyLinearVelocity
	 * @param {String} bodyKey
	 * @return {Object}
	 * @protected
	 */
	_getBodyLinearVelocity: function(bodyKey) {
		
		return this.getBody(bodyKey).physicsHandle.GetLinearVelocity();
		
	},
	
	/**
	 * Destroys given body
	 * 
	 * @method _destroyBody
	 * @param {String} bodyKey
	 * @protected
	 */
	_destroyBody: function(bodyKey) {
		
		var found=false;
		
		for (var i=0;i<this.bodies.length;i++) {
			
			if (this.bodies[i].key==bodyKey) {
				found=true;
				break;
			}
			
		}
		
		if (!found) return;
		
		this._engine.physics.scheduleDestroyBody(
			this,
			this.getBody(bodyKey)
		);
		
		this.bodies.splice(i,1);
		
		return true;
		
	}
	
});