1 /*
  2 Copyright (C) 2011  Mikael Brandt & Mikael Logart
  3 
  4 The JavaScript code in this file is free software: you can
  5 redistribute it and/or modify it under the terms of the GNU
  6 General Public License (GNU GPL) as published by the Free Software
  7 Foundation, either version 3 of the License, or (at your option)
  8 any later version.  The code is distributed WITHOUT ANY WARRANTY;
  9 without even the implied warranty of MERCHANTABILITY or FITNESS
 10 FOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.
 11 
 12 As additional permission under GNU GPL version 3 section 7, you
 13 may distribute non-source (e.g., minimized or compacted) forms of
 14 that code without the copy of the GNU GPL normally required by
 15 section 4, provided you include this license notice and a URL
 16 through which recipients can access the Corresponding Source.
 17 */
 18 /**
 19  * @namespace Engine namespace.
 20  * @ignore
 21  */
 22 var VENISON = {
 23 	/**
 24 	 * @namespace Namespace for entity-specific classes.
 25 	 * @ignore
 26 	 */
 27 	ENTITY: {},
 28 	/**
 29 	 * @namespace Namespace for game states.
 30 	 * @ignore
 31 	 */
 32 	GAMESTATES: {},
 33 	/**
 34 	 * @namespace Namespace for general classes.
 35 	 * @ignore
 36 	 */
 37 	GENERAL: {},
 38 	/**
 39 	 * @namespace Namespace for graphics related classes.
 40 	 * @ignore
 41 	 */
 42 	GRAPHICS: {},
 43 	/**
 44 	 * @namespace Namespace for messages.
 45 	 * @ignore
 46 	 */
 47 	MESSAGES: {},
 48 	/**
 49 	 * @namespace Namespace for network.
 50 	 * @ignore
 51 	 */
 52 	NETWORK: {},
 53 	/**
 54 	 * @namespace Namespace for physics.
 55 	 * @ignore
 56 	 */
 57 	PHYSICS: {},
 58 	/**
 59 	 * @namespace Namespace for properties.
 60 	 * @ignore
 61 	 */
 62 	PROPERTY: {},
 63 	/**
 64 	 * @namespace Namespace for tools.
 65 	 * @ignore
 66 	 */
 67 	TOOLS: {},
 68 	/**
 69 	 * @class Namespace for utilities.
 70 	 */
 71 	UTILITIES: {},
 72 	/**
 73 	 * @namespace Namespace for our in-house physics engine.
 74 	 * @ignore
 75 	 */
 76 	VENISONPHYSICS: {},
 77 	/**
 78 	 * @namespace Namespace for audio.
 79 	 * @ignore
 80 	 */
 81 	AUDIO: {},
 82 
 83 	/**
 84 	 * @namespace Namespace for global variables such as file paths.
 85 	 *
 86 	 */
 87 	VARS: {
 88 		mainCanvas: null,
 89 		levelsDir: '/levels',
 90 		audioDir: '/audio',
 91 		imagesDir: '/images'
 92 	}
 93 
 94 };
 95 (function () {
 96 	/**
 97 	 * @class A 2D Vector utility class.
 98 	 * @param {Number} iX The horizontal component of the vector.
 99 	 * @param {Number} iY The vertical component of the vector.
100 	 */
101 	VENISON.UTILITIES.Vector2 = function (iX, iY) {
102 		var Vector2 = VENISON.UTILITIES.Vector2; //Convenience caching
103 		/**
104 		 * The horizontal component of the vector.
105 		 * @fieldOf VENISON.UTILITIES.Vector2.prototype
106 		 * @name x
107 		 * @type Number
108 		 */
109 		this.x = iX;
110 		/**
111 		 * The vertical component of the vector.
112 		 * @fieldOf VENISON.UTILITIES.Vector2.prototype
113 		 * @name y
114 		 * @type Number
115 		 */
116 		this.y = iY;
117 		/**
118 		 * Copy the vector.
119 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
120 		 * @name fnCopy
121 		 * @returns {VENISON.UTILITIES.Vector2} A new Vector2 that is identical to the original one.
122 		 */
123 		this.fnCopy = function () {
124 			return new Vector2(this.x, this.y);
125 		}
126 		/**
127 		 * Add a vector to this one.
128 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
129 		 * @name fnAdd
130 		 * @param {VENISON.UTILITIES.Vector2} iVector The vector to add to this one.
131 		 * @returns {VENISON.UTILITIES.Vector2} A new Vector2.
132 		 */
133 		this.fnAdd = function (iVector) {
134 			return new Vector2(this.x + iVector.x, this.y + iVector.y);
135 		}
136 		/**
137 		 * Subtract a vector from this one.
138 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
139 		 * @name fnSubtract
140 		 * @param {VENISON.UTILITIES.Vector2} iVector The vector to subtract from this one.
141 		 * @returns {VENISON.UTILITIES.Vector2} A new Vector2.
142 		 */
143 		this.fnSubtract = function (iVector) {
144 			return new Vector2(this.x - iVector.x, this.y - iVector.y);
145 		}
146 		/**
147 		 * Get the length of the vector.
148 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
149 		 * @name fnLength
150 		 * @returns {Number} The length of this vector.
151 		 */
152 		this.fnLength = function () {
153 			return Math.sqrt(this.x * this.x + this.y * this.y);
154 		}
155 		/**
156 		 * Get the square length of the vector.
157 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
158 		 * @name fnLengthSquared
159 		 * @returns {Number} The square length of this vector.
160 		 */
161 		this.fnLengthSquared = function () {
162 			return this.x * this.x + this.y * this.y;
163 		}
164 		/**
165 		 * Multiply the vector with a scalar. Returns the result, leaving this Vector2 unaffected.
166 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
167 		 * @name fnMultiplyScalar
168 		 * @param {Number} iScalar The scalar value to multiply this vector with.
169 		 * @returns {VENISON.UTILITIES.Vector2} The result of the scalar multiplication.
170 		 */
171 		this.fnMultiplyScalar = function (iScalar) {
172 			return new Vector2(this.x*iScalar, this.y*iScalar);
173 		}
174 		/**
175 		 * Increment the values of the vector.
176 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
177 		 * @name fnIncrementBy
178 		 * @param {VENISON.UTILITIES.Vector2} iVector The vector containing the values to increment this vector by.
179 		 */
180 		this.fnIncrementBy = function (iVector) {
181 			this.x += iVector.x;
182 			this.y += iVector.y;
183 		}
184 		/**
185 		 * Calculate the dot product between this vector and another.
186 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
187 		 * @name fnDot
188 		 * @param {VENISON.UTILITIES.Vector2} iVector The vector to scalarly multiply this vector with.
189 		 * @returns {Number} The dot product.
190 		 */
191 		this.fnDot = function (iVector) {
192 			return this.x * iVector.x + this.y * iVector.y;
193 		}
194 		/**
195 		 * Calculate the cross product between this vector and another.
196 		 * NOTE: The cross product is not actually defined in 2D, but no one can stop us from pretending!
197 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
198 		 * @name fnCross
199 		 * @param {VENISON.UTILITIES.Vector2} iVector The vector to cross this vector with.
200 		 * @returns {Number} This function returns the scalar value of the z-component of the vector derived from the cross product of this vector and iVector, when pretending they are 3D vectors with 0 as their z-values.
201 		 */
202 		this.fnCross = function (iVector) {
203 			return this.x * iVector.y - this.y * iVector.x;
204 		}
205 		/**
206 		 * Negate the vector.
207 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
208 		 * @name fnNegated
209 		 * @returns {VENISON.UTILITIES.Vector2} A new Vector2.
210 		 */
211 		this.fnNegated = function () {
212 			return new Vector2(-this.x, -this.y);
213 		}
214 		/**
215 		 * Get a rotated version of this Vector2. This Vector2 is not affected.
216 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
217 		 * @name fnRotate
218 		 * @param {Number} iAngle The angle in radians.
219 		 * @returns {VENISON.UTILITIES.Vector2} The rotated Vector2.
220 		 */
221 		this.fnRotate = function (iAngle) {
222 			return new Vector2(Math.cos(iAngle)*this.x - Math.sin(iAngle)*this.y, Math.sin(iAngle)*this.x + Math.cos(iAngle)*this.y);
223 		}
224 		/**
225 		 * Normalize the vector.
226 		 * @methodOf VENISON.UTILITIES.Vector2.prototype
227 		 * @name fnNormalize
228 		 */
229 		this.fnNormalize = function () {
230 			var inverseLength = 1 / this.fnLength();
231 			this.x *= inverseLength;
232 			this.y *= inverseLength;
233 		}
234 	}
235 	/**
236 	 * @class A transformation utility class used by the Venison Engine. Contains position, rotation and scale.
237 	 * @param {Number} iX The x component of the position vector.
238 	 * @param {Number} iY The y component of the position vector.
239 	 * @param {Number} iRot The rotation.
240 	 * @param {Number} iScaleX The x component of the scale vector.
241 	 * @param {Number} iScaleY The y component of the scale vector.
242 	 */
243 	VENISON.UTILITIES.Transformation = function (iX,iY,iRot,iScaleX,iScaleY) {
244 		var Vector2 = VENISON.UTILITIES.Vector2; //Convenience caching
245 		/**
246 		 * A {@link VENISON.UTILITIES.Vector2} representing the position.
247 		 * @fieldOf VENISON.UTILITIES.Transformation.prototype
248 		 * @name position
249 		 * @type VENISON.UTILITIES.Vector2
250 		 */
251 		this.position = new Vector2(iX ? iX : 0, iY ? iY : 0);
252 		/**
253 		 * The rotation in radians.
254 		 * @fieldOf VENISON.UTILITIES.Transformation.prototype
255 		 * @name rotation
256 		 * @type Number
257 		 */
258 		this.rotation = iRot ? iRot : 0;
259 		/**
260 		 * A {@link VENISON.UTILITIES.Vector2} representing the scale.
261 		 * @fieldOf VENISON.UTILITIES.Transformation.prototype
262 		 * @name scale
263 		 * @type VENISON.UTILITIES.Vector2
264 		 */
265 		this.scale = new Vector2(iScaleX ? iScaleX : 1, iScaleY ? iScaleY : 1);
266 		/**
267 		 * Transform a point from world coordinates to object coordinates.
268 		 * @methodOf VENISON.UTILITIES.Transformation.prototype
269 		 * @name fnWorldToLocal
270 		 * @param {VENISON.UTILITIES.Vector2} iPoint The point in world space to transform to local space.
271 		 * @returns {VENISON.UTILITIES.Vector2} The point in local space.
272 		 */
273 		this.fnWorldToLocal = function (iPoint) {
274 			var originToPoint = iPoint.fnSubtract(this.position);
275 			var result = originToPoint.fnRotate(-this.rotation);
276 			result.x /= this.scale.x;
277 			result.y /= this.scale.y;
278 			return result;
279 		}
280 		/**
281 		 * Transform a point from object coordinates to world coordinates.
282 		 * @methodOf VENISON.UTILITIES.Transformation.prototype
283 		 * @name fnLocalToWorld
284 		 * @param {VENISON.UTILITIES.Vector2} iPoint The point in local space to transform to world space.
285 		 * @returns {VENISON.UTILITIES.Vector2} The point in world space.
286 		 */
287 		this.fnLocalToWorld = function (iPoint) {
288 			var iPointScaled = new Vector2(iPoint.x * this.scale.x, iPoint.y * this.scale.y);
289 			var result = iPointScaled.fnRotate(this.rotation);
290 			return this.position.fnAdd(result);
291 		}
292 		/**
293 		 * Copy function
294 		 * @methodOf VENISON.UTILITIES.Transformation.prototype
295 		 * @name fnCopy
296 		 * @returns {VENISON.UTILITIES.Transformation} A new Transformation that is identical to this one.
297 		 */
298 		this.fnCopy = function () {
299 			return new VENISON.UTILITIES.Transformation (this.position.x, this.position.y, this.rotation, this.scale.x, this.scale.y);
300 		}
301 	}
302 	/**
303 	 * Recursive function used to find a certain value in an array of objects.
304 	 * @methodOf VENISON.UTILITIES
305 	 * @name gfnFindIndexOfElementWithCertainMemberValue
306 	 * @param {Array} iArray An array of objects, sorted on their values of iMemberName.
307 	 * @param {String} iMemberName The attribute name of whose value the objects are sorted by.
308 	 * @param {Number} iMemberValue The value to find.
309 	 * @returns {Number} The index of the element in the array such that element[iMemberName] === iMemberValue.
310 	 */
311 	var gfnFindIndexOfElementWithCertainMemberValue = VENISON.UTILITIES.gfnFindIndexOfElementWithCertainMemberValue = function (iArray, iMemberName, iMemberValue) {
312 		var numElements = iArray.length;
313 		if (numElements === 1) {
314 			if (iArray[0][iMemberName] === iMemberValue) {
315 				return 0;
316 			}
317 			return null;
318 		}
319 		var middleIndex = Math.floor(numElements/2);
320 		if (iArray[middleIndex][iMemberName] === iMemberValue) {
321 			return middleIndex;
322 		}
323 		if (iArray[middleIndex][iMemberName] > iMemberValue) {
324 			return gfnFindIndexOfElementWithCertainMemberValue(iArray.slice(0,middleIndex), iMemberName, iMemberValue);
325 		}
326 		return middleIndex + 1 + gfnFindIndexOfElementWithCertainMemberValue(iArray.slice(middleIndex + 1), iMemberName, iMemberValue);
327 
328 	}
329 	/**
330 	 * Parse a String representation of an XML document and return the resulting DOM XML Object.
331 	 * @methodOf VENISON.UTILITIES
332 	 * @name gfnGetDOMFromXMLString
333 	 * @param {String} iXMLString A String representation of an XML document.
334 	 * @returns {Object} The resulting DOM XML Object.
335 	 */
336 	VENISON.UTILITIES.gfnGetDOMFromXMLString = function (iXMLString) {
337 		var xmlDoc = null;
338 		if (window.DOMParser) {
339 			var parser=new DOMParser();
340 			xmlDoc=parser.parseFromString(iXMLString,"text/xml");
341 		} else {// Internet Explorer
342 			xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
343 			xmlDoc.async="false";
344 			xmlDoc.loadXML(iXMLString);
345 		}
346 		return xmlDoc;
347 	}
348 	/**
349 	 * Create an String representation of an XML document from a DOM XML Object.
350 	 * @methodOf VENISON.UTILITIES
351 	 * @name gfnGetXMLStringFromDOM
352 	 * @param {Object} iDOM The DOM XML Object to create an XML String from.
353 	 * @returns A String representation of the DOM XML Object or null if the browser doesn't have support for this.
354 	 */
355 	VENISON.UTILITIES.gfnGetXMLStringFromDOM = function (iDOM) {
356 		if (XMLSerializer) {
357 			// Gecko- and Webkit-based browsers (Firefox, Chrome), Opera.
358 			return (new XMLSerializer()).serializeToString(iDOM);
359 		} else if (iDOM.xml) { //IE. I know nothing will work in IE anyway right now, but might as well have it here
360 			return iDOM.xml;
361 		}
362 		//If we reach this, there is no support
363 		return null;
364 
365 	}
366 	/**
367 	 * Get all the child elements of iElement, stored in an Array.
368 	 * @methodOf VENISON.UTILITIES
369 	 * @name gfnGetChildElements
370 	 * @param {Object} iElement The element to extract child elements from.
371 	 * @returns {Array} An Array containing all the child elements of iElement.
372 	 */
373 	VENISON.UTILITIES.gfnGetChildElements = function (iElement) {
374 		var childNodes = iElement.childNodes;
375 		var result = [];
376 		var numChildNodes = childNodes.length;
377 		for (var i = 0; i < numChildNodes; i++) {
378 			if (childNodes[i].nodeType === 1) {//If it is something else than an element, don't add it to the array
379 				result.push(childNodes[i]);
380 			}
381 		}
382 		return result;
383 	}
384 	/**
385 	 * Get the cookie with name iName.
386 	 * @methodOf VENISON.UTILITIES
387 	 * @name gfnGetCookie
388 	 * @param {String} iName The name of the cookie.
389 	 * @returns {String} The value of the cookie if it exists, otherwise undefined.
390 	 */
391 	VENISON.UTILITIES.gfnGetCookie = function (iName) {
392 		var i,x,y,ARRcookies=document.cookie.split(";");
393 		var ARRcookiesLength = ARRcookies.length;
394 		for (i=0;i<ARRcookiesLength;i++) {
395 			x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
396 			y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
397 			x=x.replace(/^\s+|\s+$/g,"");
398 			if (x===iName) {
399 				return unescape(y);
400 			}
401 		}
402 	}
403 	/**
404 	 * Set a cookie.
405 	 * @methodOf VENISON.UTILITIES
406 	 * @name gfnSetCookie
407 	 * @param {String} iName The name of the cookie.
408 	 * @param {String} iValue The value of the cookie.
409 	 * @param {Number} iExDays The days the cookie should exist before it expires.
410 	 */
411 	VENISON.UTILITIES.gfnSetCookie = function (iName,iValue, iExDays) {
412 		var exdate=new Date();
413 		exdate.setDate(exdate.getDate() + iExDays);
414 		var value=escape(iValue) + ((iExDays===null) ? "" : "; expires="+exdate.toUTCString());
415 		document.cookie=iName + "=" + value;
416 	}
417 })();
418 (function() {
419 	/**
420 	 * @class Singleton used for storing and updating entities.
421 	 */
422 	VENISON.ENTITY.EntityManager = new function() {
423 		//private
424 		var mEntities = []; //An array to contain all game entities
425 		var mUnusedIDs = [];
426 		var mEntitiesByName = {};
427 		var mEntitiesToRemove = [];
428 
429 		/**
430 		 * Set the entity name.
431 		 * IMPORTANT: DO NOT CALL EXPLICITLY! Only used internally. Called from within {@link VENISON.ENTITY.GameEntity#fnSetName}.
432 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
433 		 * @param {VENISON.ENTITY.GameEntity} iEntity The entity to set the name of.
434 		 * @param {String} iName The name to give the entity. Has to be a valid, unique String.
435 		 * @returns {Boolean} True if the name was succesfully set, false if the name is currently in use by another entity.
436 		 * @ignore
437 		 */
438 		this.fnSetEntityName = function(iEntity, iName) {
439 			if (!iName) {
440 				delete mEntitiesByName[iEntity.fnGetName()];
441 				return true;
442 			}
443 			if (mEntitiesByName[iName]) {
444 				return false;
445 			}
446 			delete mEntitiesByName[iEntity.fnGetName()];
447 			mEntitiesByName[iName] = iEntity;
448 			return true;
449 		}
450 		//public
451 		/**
452 		 * Give all the entities a chance to do stuff when the level has been loaded.
453 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
454 		 * @ignore
455 		 */
456 		this.fnOnLevelLoaded = function() {
457 			var numEntities = mEntities.length;
458 			for (var i = 0; i < numEntities; i++) {
459 				mEntities[i].fnOnLevelLoaded();
460 			}
461 		}
462 		/**
463 		 * Function called every frame to update the entities.
464 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
465 		 * @ignore
466 		 */
467 		this.fnUpdate = function() {
468 			var numEntities = mEntities.length;
469 			for (var i = 0; i < numEntities; i++) {
470 				if (mEntities[i]) { //There may be gaps in the array due to removal of entities
471 					mEntities[i].fnOnFrame();
472 				}
473 			}
474 			mfnRemoveEntities();
475 		}
476 		/**
477 		 * Register a game entity with the EntityManager.
478 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
479 		 * @name fnRegisterEntity
480 		 * @param {VENISON.ENTITY.GameEntity} iEntity The entity to register.
481 		 */
482 		this.fnRegisterEntity = function(iEntity) {
483 			if (mUnusedIDs.length > 0) {
484 				iEntity.id = mUnusedIDs.pop();
485 				mEntities[iEntity.id] = iEntity;
486 			} else {
487 				iEntity.id = mEntities.length;
488 				mEntities.push(iEntity);
489 			}
490 
491 		}
492 		/**
493 		 * Remove an entity from the game immediately, freeing its ID.
494 		 * NOTE: Don't use from physics callback. Preferably use {@link VENISON.ENTITY.EntityManager#fnRemoveEntity} instead.
495 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
496 		 * @name fnRemoveEntityImmediately
497 		 * @param {VENISON.ENTITY.GameEntity} iEntity The entity to remove.
498 		 */
499 		this.fnRemoveEntityImmediately = function(iEntity) {
500 			iEntity.fnOnRemoved();
501 			var entityID = iEntity.id;
502 			mUnusedIDs.push(entityID);
503 			iEntity.id = -1;
504 			delete mEntities[entityID];
505 			delete iEntity;
506 		}
507 		var that = this;
508 		/**
509 		 * Remove all the entities currently queued for removal.
510 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
511 		 * @ignore
512 		 */
513 		function mfnRemoveEntities() {
514 			var numEntitiesToRemove = mEntitiesToRemove.length;
515 			for (var i = 0; i < numEntitiesToRemove; i++) {
516 				var entity = mEntitiesToRemove[i];
517 				if (entity.id != -1) {
518 					that.fnRemoveEntityImmediately(entity);
519 				}
520 			}
521 			mEntitiesToRemove = [];
522 		}
523 
524 		/**
525 		 * Register a game entity to be removed from the game during the next frame.
526 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
527 		 * @name fnRemoveEntity
528 		 * @param {VENISON.ENTITY.GameEntity} iEntity The entity to remove.
529 		 */
530 		this.fnRemoveEntity = function(iEntity) {
531 			mEntitiesToRemove.push(iEntity);
532 		}
533 		/**
534 		 * Get a game entity by its name.
535 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
536 		 * @name fnGetEntityByName
537 		 * @param {Object} iName The name of the entity.
538 		 * @returns {VENISON.ENTITY.GameEntity} The entity with the name iName.
539 		 */
540 		this.fnGetEntityByName = function(iName) {
541 			return mEntitiesByName[iName];
542 		}
543 		/**
544 		 * Get a game entity by its ID.
545 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
546 		 * @name fnGetEntityByID
547 		 * @param {Number} iID The ID of the entity.
548 		 * @returns {VENISON.ENTITY.GameEntity} The entity with the ID iID.
549 		 */
550 		this.fnGetEntityByID = function(iID) {
551 			return mEntities[iID];
552 		}
553 		/**
554 		 * Get all the entities that are registered with the EntityManager.
555 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
556 		 * @name fnGetEntities
557 		 * @returns {Array} The array of all the entities currently registered with the EntityManager.
558 		 */
559 		this.fnGetEntities = function() {
560 			return mEntities;
561 		}
562 		/**
563 		 * Get the total number of entities registered with the EntityManager.
564 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
565 		 * @name fnGetNumberOfEntities
566 		 * @returns {Number} The total number of entities registered with the EntityManager.
567 		 */
568 		this.fnGetNumberOfEntities = function() {
569 			return mEntities.length - mUnusedIDs.length;
570 		}
571 		/**
572 		 * Give all the entities a chance to do stuff when the current level is unloaded.
573 		 * @methodOf VENISON.ENTITY.EntityManager.prototype
574 		 * @ignore
575 		 */
576 		this.fnOnLevelUnloaded = function() {
577 			var numEntities = mEntities.length;
578 			for (var i = numEntities - 1; i >= 0; i--) {
579 				if (mEntities[i]) { //There may be gaps in the array due to removal of entities
580 					this.fnRemoveEntityImmediately(mEntities[i]);
581 
582 				}
583 			}
584 			mEntities.length = 0; //If we don't do this, the array will be empty but have the same length as the maximum number of entities at any time during this level.
585 			mUnusedIDs = [];
586 			mEntitiesByName = {};
587 			mEntitiesToRemove = [];
588 		}
589 	}
590 })();
591 (function () {
592 	/**
593 	 * @class Singleton used for updating animations and storing animation image data.
594 	 */
595 	VENISON.GRAPHICS.AnimationManager = new function () {
596 
597 		/**
598 		 * Creates a new Animation.
599 		 * @class AnimationManager helper class.
600 		 * @param {String} iAnimationName The name of the animation
601 		 * @param {Number} iFrameTime The time each frame should be visible
602 		 * @param {Number} iStartFrame The frame to start playing the animation from
603 		 * @param {Boolean} iLoop True if the animation should loop
604 		 * @param {Function} iCallbackFunction The function to call when animation has finished playing
605 		 * @ignore
606 		 */
607 		function Animation(iAnimationName, iFrameTime, iStartFrame, iLoop, iCallbackFunction) {
608 			this.animation = iAnimationName;
609 			this.frameTime = iFrameTime;
610 			this.currentFrame = iStartFrame;
611 			this.timeLast = 0;
612 			this.looping = iLoop;
613 			this.callback = iCallbackFunction;
614 			this.paused = false;
615 		}
616 
617 		var mAnimations = {}; //Stores image data for animations and default framerates
618 		var mAnimatedEntities = []; //Stores entities that are currently being animated and their animation
619 
620 		/**
621 		 * Pause or unpause the animation currently playing for the entity with ID iEntityID.
622 		 * @param {Number} iEntityID The id of the entity whose animation's pause state should be set.
623 		 * @param {Boolean} iPaused true if the animation should be paused, otherwise false.
624 		 * @methodOf VENISON.GRAPHICS.AnimationManager.prototype
625 		 * @name fnSetAnimationPaused
626 		 */
627 		this.fnSetAnimationPaused = function (iEntityID, iPaused) {
628 			mAnimatedEntities[iEntityID].animation.paused = iPaused;
629 		}
630 		/**
631 		 * Called once every frame to update all playing animations.
632 		 * @methodOf VENISON.GRAPHICS.AnimationManager.prototype
633 		 * @ignore
634 		 */
635 		this.fnUpdate = function () {
636 			var d = new Date();
637 			var timeNow = d.getTime();
638 			var numAnimatedEntities = mAnimatedEntities.length;
639 			for(var i = 0; i < numAnimatedEntities; i++) {
640 				var ae = mAnimatedEntities[i];
641 				if (!ae) {
642 					continue;
643 				}
644 				var entityAnim = ae.animation;
645 
646 				if(entityAnim.paused) {
647 					entityAnim.timeLast = timeNow;
648 					continue;
649 				}
650 				var numFramesToAdvance = Math.floor((timeNow - entityAnim.timeLast) / entityAnim.frameTime);
651 				if( numFramesToAdvance > 0 ) {
652 					entityAnim.currentFrame += numFramesToAdvance;
653 					var numFramesTotal = mAnimations[entityAnim.animation].frames.length;
654 					var numFramesBeyondEnding = (entityAnim.currentFrame - numFramesTotal) % numFramesTotal;
655 					if (numFramesBeyondEnding >= 0) { //Was this the last frame in the animation?
656 						if(entityAnim.looping) { //Should the animation loop?
657 							entityAnim.currentFrame = numFramesBeyondEnding;
658 						} else { //Else remove the animation and call the callback funtion
659 							delete mAnimatedEntities[i];
660 							if (entityAnim.callback) {
661 								entityAnim.callback();
662 							}
663 							continue;
664 						}
665 					}
666 					//Set the texture to the next frame
667 					ae.entity.graphicsImage = mAnimations[entityAnim.animation].frames[entityAnim.currentFrame];
668 					entityAnim.timeLast = timeNow;
669 				}
670 			}
671 		}
672 		/**
673 		 * Register animations and stores them in the AnimationManager.
674 		 * @methodOf VENISON.GRAPHICS.AnimationManager.prototype
675 		 * @name fnRegisterAnimation
676 		 * @param {String} iAnimationName Name of the animation.
677 		 * @param {Array} iAnimation Contains every image in the animation in order.
678 		 * @param {Number} iFrameRate Default framerate for the animation.
679 		 */
680 		this.fnRegisterAnimation = function (iAnimationName, iAnimation, iFrameRate) {
681 			if(!mAnimations[iAnimationName]) {
682 				mAnimations[iAnimationName] = {
683 					frames: iAnimation,
684 					frameRate: iFrameRate
685 				};
686 			}
687 		}
688 		/**
689 		 * Function used to play animations.
690 		 * @methodOf VENISON.GRAPHICS.AnimationManager.prototype
691 		 * @name fnPlayAnimation
692 		 * @param {String} iAnimationName The name of the animation to play.
693 		 * @param {Object} iEntity The entity that wants to play the animation.
694 		 * @param {Number} iFrameRate Number of frames per second, if no value is given (or the value is 0) the default framerate for the animation will be used.
695 		 * @param {Number} iStartFrame The frame to begin playing the animation from, has to be a valid frame.
696 		 * @param {Boolean} iLoop true if animation should loop.
697 		 * @param {Function} iCallbackFunction The function to call when animation is finished.
698 		 */
699 		this.fnPlayAnimation = function (iAnimationName, iEntity, iFrameRate, iStartFrame, iLoop, iCallbackFunction) {
700 			//Check if an animation with this name already exists
701 			var anim = mAnimations[iAnimationName];
702 			if(!anim) {
703 				return;
704 			}
705 			//Remove any previous animations that this entity might be playing
706 			delete mAnimatedEntities[iEntity.id];
707 			//Create a new animation for this entity
708 			var d = new Date();
709 
710 			var fr = iFrameRate ? iFrameRate : anim.frameRate;
711 			var startFrame = iStartFrame ? iStartFrame : 0;
712 			var loop = iLoop ? true : false;
713 			var newAnim = new Animation(iAnimationName, 1000/fr, startFrame, loop, iCallbackFunction);
714 			newAnim.timeLast = d.getTime();
715 			mAnimatedEntities[iEntity.id] = {
716 				animation: newAnim,
717 				entity: iEntity
718 			};
719 			iEntity.graphicsImage = anim.frames[startFrame];
720 		}
721 	}
722 })();
723 (function () {
724 	/**
725 	 * @class Message class. Contains message type, sender & receiver ID and message contents.
726 	 * @param {String} iType The type of message to create.
727 	 * @param {Number} iTo The ID of the receiver.
728 	 * @param {Number} iFrom The ID of the sender.
729 	 * @param {Object} iContent Message specific content.
730 	 */
731 	VENISON.MESSAGES.Message = function (iType,iTo,iFrom,iContent) {
732 		//public
733 		/**
734 		 * The message type.
735 		 * @type String
736 		 */
737 		this.type = iType;
738 		/**
739 		 * The ID of the receiver.
740 		 * @type Number
741 		 */
742 		this.to = iTo;
743 		/**
744 		 * A Number representing the ID of the sender.
745 		 * @type Number
746 		 */
747 		this.from = iFrom;
748 		/**
749 		 * An Object containing message specific content.
750 		 * @type Object
751 		 */
752 		this.content = iContent;
753 	}
754 })();
755 (function () {
756 	var EntityManager = VENISON.ENTITY.EntityManager;
757 	// Dispatches messages to entities
758 
759 	/**
760 	 * @class Singleton used for dispatching messages.
761 	 */
762 	VENISON.MESSAGES.MessageManager = new function () {
763 		var mMessages = [];
764 		var mEntities = EntityManager.fnGetEntities();
765 
766 		function mfnStoreDelayedMessage(iMessage, iDelay) {
767 			var now = (new Date()).getTime();
768 			iMessage.dispatchTime = now + iDelay;
769 			if (mMessages.length === 0) {
770 				mMessages.push(iMessage);
771 			} else {
772 				var iterator = mMessages.length - 1;
773 				var temp = mMessages[iterator];
774 				mMessages.push(iMessage);
775 
776 				while (temp.dispatchTime <= iMessage.dispatchTime) {
777 					mMessages[iterator + 1] = temp;
778 					if (--iterator < 0 ) {
779 						break;
780 					}
781 					temp = mMessages[iterator];
782 				}
783 				mMessages[iterator + 1] = iMessage;
784 			}
785 		}
786 
787 		/**
788 		 * Sends a message to an entity. If a delay is specified the message will be stored in the MessageManager until sufficient time has passed.
789 		 * @methodOf VENISON.MESSAGES.MessageManager.prototype
790 		 * @name fnSendMessage
791 		 * @param {VENISON.MESSAGES.Message} iMessage The message to be sent.
792 		 * @param {Number} iDelay The delay in milliseconds before the message is sent.
793 		 */
794 		this.fnSendMessage = function (iMessage, iDelay) {
795 			if (!iDelay || iDelay <= 0) { // Send right away
796 				var receiver = mEntities[iMessage.to];
797 				if (receiver) {
798 					receiver.fnHandleMessage(iMessage);
799 				}
800 			} else { // Store message to send later
801 				mfnStoreDelayedMessage(iMessage, iDelay);
802 			}
803 		}
804 		/**
805 		 * Function called every frame to check if any delayed messages are ready for dispatching.
806 		 * @methodOf VENISON.MESSAGES.MessageManager.prototype
807 		 * @ignore
808 		 */
809 		this.fnUpdate = function () {
810 			var numDelayedMessages = mMessages.length;
811 			if (numDelayedMessages > 0) {
812 				var now = (new Date()).getTime();
813 				var msg;
814 				while (numDelayedMessages > 0) {
815 					msg = mMessages[numDelayedMessages - 1]; //The earliest message is the last one in the array
816 					if (msg.dispatchTime > now) { //If the earliest message is supposed to be sent later than now, we are done.
817 						break;
818 					}
819 					this.fnSendMessage(msg); //Send the message without delay
820 					mMessages.pop();
821 					numDelayedMessages--;
822 				}
823 			}
824 		}
825 	}
826 })();
827 (function () {
828 	var Vector2 = VENISON.UTILITIES.Vector2;
829 
830 	/**
831 	 * @class Singleton used for playing sounds.
832 	 */
833 	VENISON.AUDIO.AudioManager = new function () {
834 		//Sound dictionary with arrays as values
835 		var mSounds = {};
836 		var mRepeatingSounds = [];
837 		var mDynamicSounds = [];
838 		/**
839 		 * The point from which all dynamic sounds should be heard.
840 		 * NOTE: Since this is a reference to a vector, the point of interest will update along with the referred one.
841 		 * @fieldOf VENISON.AUDIO.AudioManager.prototype
842 		 * @name pointOfInterest
843 		 * @default {x:0, y:0}
844 		 * @type VENISON.UTILITIES.Vector2
845 		 */
846 		this.pointOfInterest = new Vector2(0,0); //Vector2
847 		/**
848 		 * Everything is heard normally within this distance from the point of interest.
849 		 * @fieldOf VENISON.AUDIO.AudioManager.prototype
850 		 * @name innerCircleRadius
851 		 * @default 50
852 		 * @type Number
853 		 */
854 		this.innerCircleRadius = 50;
855 		/**
856 		 * No sound is heard outside of this distance. In the space between this distance and innerCircleRadius, volume is lowered.
857 		 * @fieldOf VENISON.AUDIO.AudioManager.prototype
858 		 * @name outerCircleRadius
859 		 * @default 150
860 		 * @type Number
861 		 */
862 		this.outerCircleRadius = 150;
863 		/**
864 		 * Function called once every frame to update the volume of dynamic sounds.
865 		 * @methodOf VENISON.AUDIO.AudioManager.prototype
866 		 * @ignore
867 		 */
868 		this.fnUpdate = function () {
869 			//Go through all dynamic sounds and update their volumes
870 			var numDynamicSounds = mDynamicSounds.length;
871 			for(var i = 0; i < numDynamicSounds; i++) {
872 				var currentPos = mDynamicSounds[i].position;
873 				var sound = mDynamicSounds[i].audio;
874 				var diff = currentPos.fnSubtract(this.pointOfInterest);
875 				var dist = diff.fnLength();
876 
877 				if(dist < this.innerCircleRadius) {
878 					sound.volume = 1.0;
879 				} else if(dist > this.outerCircleRadius) {
880 					sound.volume = 0.0;
881 				} else {
882 					var newVolume = 1-((dist-this.innerCircleRadius)/(this.outerCircleRadius-this.innerCircleRadius));
883 					sound.volume = newVolume;
884 				}
885 			}
886 		}
887 		/**
888 		 * Add the sound to the sound dictionary.
889 		 * @methodOf VENISON.AUDIO.AudioManager.prototype
890 		 * @param {String} iSoundName The name of the sound.
891 		 * @param {Object} iAudioElement The HTML5 Audio element to add.
892 		 * @ignore
893 		 */
894 		function mfnAddSound(iSoundName, iAudioElement) {
895 			if(!mSounds[iSoundName]) {
896 				mSounds[iSoundName] = [];
897 			}
898 			mSounds[iSoundName].push(iAudioElement);
899 		}
900 
901 		/**
902 		 * Load sound from path excluding file suffix. fnLoadSound will try to load the sound in a format that is compatible with the current browser.
903 		 * @methodOf VENISON.AUDIO.AudioManager.prototype
904 		 * @name fnLoadSound
905 		 * @param iSoundName The name the sound will be known by in the AudioManager.
906 		 * @param iFilePath The relative path to the file including the file name without the suffix, e.g 'audioFolder/testAudioFile'.
907 		 * @returns {Boolean} false if browser does not support ogg, mp3 or wav. If support was detected, return true and try to load the file.
908 		 */
909 		this.fnLoadSound = function (iSoundName, iFilePath) {
910 			if(!Modernizr.audio) { //Let Modernizr detect html5 audio tag support
911 				log('Your browser does not support the html5 audio tag =,(');
912 			}
913 
914 			iFilePath = VENISON.VARS.audioDir + '/' + iFilePath;
915 
916 			var newAudio = document.createElement('audio');
917 			newAudio.autoplay = false;
918 
919 			var wavSource = document.createElement('source');
920 			wavSource.src = iFilePath + '.wav';
921 			wavSource.type = 'audio/wav';
922 
923 			var oggSource = document.createElement('source');
924 			oggSource.src = iFilePath + '.ogg';
925 			oggSource.type = 'audio/ogg';
926 
927 			var mp3Source = document.createElement('source');
928 			mp3Source.src = iFilePath + '.mp3';
929 			mp3Source.type = 'audio/mpeg';
930 
931 			newAudio.appendChild(mp3Source);
932 			newAudio.appendChild(wavSource);
933 			newAudio.appendChild(oggSource);
934 
935 			mfnAddSound(iSoundName, newAudio);
936 			newAudio.load();
937 		}
938 		/**
939 		 * Removes sound from the dynamic sounds array and resets it for later use
940 		 * @methodOf VENISON.AUDIO.AudioManager.prototype
941 		 * @ignore
942 		 */
943 		function mfnRemoveDynamicSound (iIndex) {
944 			mDynamicSounds[iIndex].audio.volume = 1.0;
945 			mDynamicSounds[iIndex] = mDynamicSounds[mDynamicSounds.length-1];
946 			mDynamicSounds.pop();
947 		}
948 
949 		/**
950 		 * Stops a repeating sound.
951 		 * @methodOf VENISON.AUDIO.AudioManager.prototype
952 		 * @name fnStopRepeatingSound
953 		 * @param {Number} iIndex The index that is used to identify the repeating sound in the VENISON.AUDIO.AudioManager.
954 		 */
955 		this.fnStopRepeatingSound = function (iIndex) {
956 			mRepeatingSounds[iIndex].loop = false;
957 			mRepeatingSounds[iIndex].pause();
958 			mRepeatingSounds[iIndex].currentTime = 0;
959 			mRepeatingSounds[iIndex] = mRepeatingSounds[mRepeatingSounds.length-1];
960 			mRepeatingSounds.pop();
961 		}
962 		/**
963 		 * Mute all sounds.
964 		 * @methodOf VENISON.AUDIO.AudioManager.prototype
965 		 * @name fnSetGlobalMute
966 		 * @param {Boolean} iMuted true if sounds should be muted, false if not.
967 		 */
968 		this.fnSetGlobalMute = function (iMuted) {
969 			for (var s in mSounds) {
970 				var a = mSounds[s];
971 				var length = a.length;
972 				for (var i = 0; i < length; i ++) {
973 					a[i].muted = iMuted;
974 				}
975 			}
976 		}
977 		/**
978 		 * Plays a sound. If parameter iPosition is supplied, the sound will be a dynamic sound. If parameter iShouldRepeat is supplied, the sound will be a repeating sound.
979 		 * @methodOf VENISON.AUDIO.AudioManager.prototype
980 		 * @name fnPlaySound
981 		 * @param {String} iSoundName The name of the sound.
982 		 * @param {VENISON.UTILITIES.Vector2} iPosition Reference to a position.
983 		 * @param {Boolean} iShouldRepeat true if sound should loop.
984 		 * @returns An index is returned for repeating sounds, which can be used to stop the sound at a later time.
985 		 */
986 		this.fnPlaySound = function (iSoundName, iPosition, iShouldRepeat) {
987 			if(!mSounds[iSoundName]) {
988 				log('In AudioManager.fnPlaySound(iSoundName): No sound named "' + iSoundName + '"');
989 				return;
990 			}
991 			//Play an audio element that is not busy
992 			var numSoundsOfType = mSounds[iSoundName].length;
993 			for(var i = 0; i < numSoundsOfType; i++) {
994 				var sound = mSounds[iSoundName][i];
995 				if((sound.ended || sound.paused)) {
996 					if(!iPosition && !iShouldRepeat) { //Should this sound neither be dynamic nor static?
997 						sound.play();
998 						return;
999 					}
1000 					var dynamicSoundsIndex = null;
1001 					if(iPosition) { //Is this a dynamic sound?
1002 						mDynamicSounds.push({
1003 							audio: sound,
1004 							position: iPosition
1005 						});
1006 						dynamicSoundsIndex = mDynamicSounds.length-1;
1007 						if(!iShouldRepeat) { //If this sound should also repeat we need to do extra stuff to it
1008 							sound.onended = function () {
1009 								mfnRemoveDynamicSound(dynamicSoundsIndex);
1010 								delete this;
1011 							}
1012 							sound.play();
1013 							return;
1014 						}
1015 					}
1016 					if(iShouldRepeat) { //Is this a repeating sound?
1017 						if(dynamicSoundsIndex != null) { //If this sound is dynamic, remove it from the list of dynamic sounds when it is paused
1018 							sound.onpause = function () {
1019 								mfnRemoveDynamicSound(dynamicSoundsIndex);
1020 								delete this;
1021 							}
1022 						}
1023 						sound.loop = true;
1024 						mRepeatingSounds.push(sound);
1025 						sound.play();
1026 
1027 						return mRepeatingSounds.length-1;
1028 					}
1029 				}
1030 			}
1031 		}
1032 	}
1033 })();
1034 (function () {
1035 	//START Setup the HUD div START
1036 
1037 	var hud = document.createElement('div');
1038 	hud.id = 'div_venisonHUD';
1039 	hud.style.position = 'absolute';
1040 
1041 	//Prevent selection of the hud
1042 	hud.addEventListener('selectstart', function (e) {
1043 		if (e.preventDefault) {
1044 			e.preventDefault();
1045 		}
1046 		return false;
1047 	}, false);
1048 	document.body.appendChild(hud);
1049 
1050 	//END Setup the HUD div END
1051 
1052 	/**
1053 	 * @class Singleton used for displaying the HUD.
1054 	 */
1055 	VENISON.GRAPHICS.HUDManager = new function () {
1056 		var mHUDs = {};
1057 
1058 		/**
1059 		 * Register HUD with the HUDManager.
1060 		 * @methodOf VENISON.GRAPHICS.HUDManager.prototype
1061 		 * @name fnRegisterHUD
1062 		 * @param {String} iName The name of the HUD.
1063 		 * @param {Function} iHUDFunction The constructor of the HUD. Should take one parameter that is the main HUD element.
1064 		 */
1065 		this.fnRegisterHUD = function (iName, iHUDFunction) {
1066 			mHUDs[iName] = iHUDFunction;
1067 		}
1068 		/**
1069 		 * Unload the current HUD.
1070 		 * @methodOf VENISON.GRAPHICS.HUDManager.prototype
1071 		 * @name fnUnloadHUD
1072 		 */
1073 		this.fnUnloadHUD = function () {
1074 			while (hud.childNodes.length) {
1075 				hud.removeChild(hud.childNodes[0]);
1076 			}
1077 		}
1078 		/**
1079 		 * Load the HUD with name iName.
1080 		 * @methodOf VENISON.GRAPHICS.HUDManager.prototype
1081 		 * @name fnLoadHUD
1082 		 * @param {Object} iName The name of the HUD to load.
1083 		 */
1084 		this.fnLoadHUD = function (iName) {
1085 			mHUDs[iName](hud);
1086 		}
1087 		/**
1088 		 * Get the main HUD element.
1089 		 * @methodOf VENISON.GRAPHICS.HUDManager.prototype
1090 		 * @name fnGetHUDElement
1091 		 */
1092 		this.fnGetHUDElement = function () {
1093 			return hud;
1094 		}
1095 		/**
1096 		 * Function to make sure the hud covers the game canvas
1097 		 * @methodOf VENISON.GRAPHICS.HUDManager.prototype
1098 		 * @name fnPositionHUD
1099 		 * @ignore
1100 		 */
1101 		this.fnPositionHUD = function() {
1102 			if (!VENISON.VARS.mainCanvas) {
1103 				log("If not in editor: hudmanager.js couldn't find game canvas!");
1104 				return;
1105 			}
1106 			hud.style.left = VENISON.VARS.mainCanvas.offsetLeft + 'px';
1107 			hud.style.top = VENISON.VARS.mainCanvas.offsetTop + 'px';
1108 			hud.style.width = VENISON.VARS.mainCanvas.width + 'px';
1109 			hud.style.height = VENISON.VARS.mainCanvas.height + 'px';
1110 		}
1111 		window.addEventListener('resize', this.fnPositionHUD, false);
1112 	}
1113 })();
1114 (function() {
1115 	/**
1116 	 * @class Singleton used for managing the states of the game.
1117 	 */
1118 	VENISON.GAMESTATES.GameStateManager = new function() {
1119 		var mGameStates = {};
1120 		var mCurrentGameState;
1121 		var mNextGameState;
1122 		/**
1123 		 * Register a game state with the GameStateManager.
1124 		 * @example //Template for implementing a new game state
1125 		 * new
1126 		 * function () {
1127 		 *    var mName = 'AnotherState';
1128 		 *    //Called once when entering this state
1129 		 *    this.fnOnEnter = function () {
1130 		 *    	//Do stuff here.
1131 		 *    }
1132 		 *    //Called once when leaving this state
1133 		 *    this.fnOnLeave = function () {
1134 		 *    	//Do stuff here.
1135 		 *    }
1136 		 *    //Returns the name of the game state to use next frame
1137 		 *    this.fnOnFrame = function () {
1138 		 *    	//Do stuff here.
1139 		 *    	return mName;
1140 		 *    }
1141 		 * 	 //Called via {@link VENISON.GAMESTATES.GameStateManager#fnHandleEvent} if this is the current state.
1142 		 *	 //@param {Object} iEvent The event, could be anything!
1143 		 *	 this.fnHandleEvent = function (iEvent) {
1144 		 *		//Handle the event here.
1145 		 *	 }
1146 		 *    //Register this state with the game state manager (no need to change when creating a new state)
1147 		 *    GameStateManager.fnRegisterGameState(this,mName);
1148 		 * }
1149 		 * @methodOf VENISON.GAMESTATES.GameStateManager.prototype
1150 		 * @name fnRegisterGameState
1151 		 * @param {Function} iGameState The game state.
1152 		 * @param {String} iName The name of the game state.
1153 		 */
1154 		this.fnRegisterGameState = function(iGameState, iName) {
1155 			mGameStates[iName] = iGameState;
1156 		}
1157 		/**
1158 		 * Set the current state of the game. The previous game state will get an opportunity to do stuff before it is replaced.
1159 		 * @methodOf VENISON.GAMESTATES.GameStateManager.prototype
1160 		 * @name fnSetState
1161 		 * @param {String} iName The name of the state.
1162 		 */
1163 		this.fnSetState = function(iName) {
1164 			//Check so that we are not trying to change to the state we are already in
1165 			if (mCurrentGameState !== mGameStates[iName]) {
1166 				mNextGameState = mGameStates[iName];
1167 			}
1168 		}
1169 		/**
1170 		 * Call the current states fnOnFrame function every frame. A state returns the next state to be set.
1171 		 * @methodOf VENISON.GAMESTATES.GameStateManager.prototype
1172 		 * @ignore
1173 		 */
1174 		this.fnUpdate = function() {
1175 			if (mNextGameState) {
1176 				if (mCurrentGameState) { //If this is the first time a state is being set, don't call fnOnLeave
1177 					mCurrentGameState.fnOnLeave();
1178 				}
1179 				mNextGameState.fnOnEnter();
1180 				mCurrentGameState = mNextGameState;
1181 				mNextGameState = null;
1182 			}
1183 			if (mCurrentGameState) {
1184 				this.fnSetState(mCurrentGameState.fnOnFrame());
1185 			}
1186 		}
1187 		/**
1188 		 * Let the current state handle events.
1189 		 * @methodOf VENISON.GAMESTATES.GameStateManager.prototype
1190 		 * @name fnHandleEvent
1191 		 * @param {Object} iEvent The event. Note that this could be anything, so it could be used very dynamically.
1192 		 */
1193 		this.fnHandleEvent = function(iEvent) {
1194 			if (mCurrentGameState.fnHandleEvent) {
1195 				mCurrentGameState.fnHandleEvent(iEvent);
1196 			}
1197 		}
1198 	}
1199 })();
1200 (function () {
1201 	/**
1202 	 * @class Adapter used to integrate Box2Dweb into the Venison Engine.
1203 	 * @ignore
1204 	 */
1205 	VENISON.PHYSICS.Box2dwebAdapter = function () {
1206 		var b2Vec2 = Box2D.Common.Math.b2Vec2;
1207 		var b2BodyDef = Box2D.Dynamics.b2BodyDef;
1208 		var b2Body = Box2D.Dynamics.b2Body;
1209 		var b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
1210 		var b2Fixture = Box2D.Dynamics.b2Fixture;
1211 		var b2World = Box2D.Dynamics.b2World;
1212 		var b2MassData = Box2D.Collision.Shapes.b2MassData;
1213 		var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
1214 		var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape;
1215 		var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;
1216 		var b2WorldManifold = Box2D.Collision.b2WorldManifold;
1217 
1218 		var Vector2 = VENISON.UTILITIES.Vector2;
1219 
1220 		var mNextCollisionBit;
1221 		var mCollisionCategories;
1222 
1223 		var mBodyPairs = [];
1224 		var mWorld;
1225 		var mMeterToPixelScale = 100.0;
1226 		var mInverseMeterToPixelScale = 1/mMeterToPixelScale;
1227 
1228 		function mfnUpdateGameEntities () {
1229 			var numBodyPairs = mBodyPairs.length;
1230 			for(var i = 0; i < numBodyPairs; i++) {
1231 				if(mBodyPairs[i]) {
1232 					var physicsPos = mBodyPairs[i].physicsBody.GetPosition();
1233 					var ge = mBodyPairs[i].gameEntity;
1234 					ge.transformation.position.x = physicsPos.x * mMeterToPixelScale;
1235 					ge.transformation.position.y = physicsPos.y * mMeterToPixelScale;
1236 					ge.transformation.rotation = mBodyPairs[i].physicsBody.GetAngle();
1237 				}
1238 			}
1239 		}
1240 
1241 		function mfnNotifyGameEntitiesInvolvedInContact(iContact, iType) {
1242 			var manifold = new b2WorldManifold();
1243 			iContact.GetWorldManifold(manifold);
1244 			var contactPosition =  new Vector2(manifold.m_points[0].x * mMeterToPixelScale, manifold.m_points[0].y * mMeterToPixelScale);
1245 			var contactNormal = new Vector2(manifold.m_normal.x, manifold.m_normal.y);
1246 
1247 			if (iType == 'preSolve') { //special strange awkward case
1248 				if (contactNormal.x === 0 && contactNormal.y === 0) { //The very special case of a preSolve-callback without contact points. I don't know when it would be useful to get such a callback (Erin Catto agrees).
1249 					return;
1250 				}
1251 				var shouldDisableContact = VENISON.PHYSICS.PhysicsManager.fnNotifyGameEntitiesOfContactEvent(iContact.GetFixtureA().GetBody().GetUserData(), iContact.GetFixtureB().GetBody().GetUserData(), contactPosition, contactNormal, iType);//Special haxx to enable disabling of contacts. Ugly, i know. I'm ashamed.
1252 
1253 				if (shouldDisableContact) {
1254 					iContact.SetEnabled(false);
1255 				}
1256 			} else { // normal case
1257 				VENISON.PHYSICS.PhysicsManager.fnNotifyGameEntitiesOfContactEvent(iContact.GetFixtureA().GetBody().GetUserData(), iContact.GetFixtureB().GetBody().GetUserData(), contactPosition, contactNormal, iType);
1258 			}
1259 
1260 		}
1261 
1262 		var mContactListener = {
1263 			BeginContact: function (iContact) {
1264 				mfnNotifyGameEntitiesInvolvedInContact(iContact, 'begin');
1265 			},
1266 			EndContact: function (iContact) {
1267 				mfnNotifyGameEntitiesInvolvedInContact(iContact, 'end');
1268 			},
1269 			PostSolve: function (iContact) {
1270 				mfnNotifyGameEntitiesInvolvedInContact(iContact, 'postSolve');
1271 			},
1272 			PreSolve: function (iContact) {
1273 				mfnNotifyGameEntitiesInvolvedInContact(iContact, 'preSolve');
1274 			}
1275 		};
1276 
1277 		this.fnInitialize = function (iLeft, iTop, iWidth, iHeight, iGravityX, iGravityY) {
1278 			var gravity = new b2Vec2(iGravityX*mInverseMeterToPixelScale, iGravityY*mInverseMeterToPixelScale);
1279 			var doSleep = true;
1280 
1281 			if(!mWorld) {
1282 				mWorld = new b2World(gravity, doSleep);
1283 
1284 				mWorld.SetContactListener(mContactListener);
1285 
1286 				mNextCollisionBit = 0x0002;
1287 				mCollisionCategories = {};
1288 				//mCollisionCategories['all'] = 0xFFFF;
1289 				mCollisionCategories['default'] = 0x0001;
1290 				//mCollisionCategories['none'] = 0x0000;
1291 			} else {
1292 				mWorld.SetGravity(gravity);
1293 			}
1294 		}
1295 		function mfnAddShapeToBody(iBody, iShape) {
1296 			//Create the shape and fixture
1297 			var fixture, shape;
1298 			switch(iShape.shapeType) {
1299 				case 'circle':
1300 					shape = new b2CircleShape();
1301 					shape.SetRadius(iShape.radius*mInverseMeterToPixelScale);
1302 					shape.SetLocalPosition(new b2Vec2(iShape.localPosition.x*mInverseMeterToPixelScale, iShape.localPosition.y*mInverseMeterToPixelScale));
1303 					break;
1304 				case 'box':
1305 					shape = new b2PolygonShape();
1306 					shape.SetAsOrientedBox(iShape.width*0.5*mInverseMeterToPixelScale, iShape.height*0.5*mInverseMeterToPixelScale, new b2Vec2(iShape.localPosition.x*mInverseMeterToPixelScale, iShape.localPosition.y*mInverseMeterToPixelScale), iShape.localRotation);
1307 					break;
1308 				case 'polygon':
1309 					shape = new b2PolygonShape();
1310 					var b2Vertices = [];
1311 					var vertices = iShape.vertices;
1312 					var count = 1;
1313 					var vertex;
1314 					//While the next vertex exists, push it to the array
1315 					while(vertex = vertices['v' + Math.floor(count / 10) + Math.floor(count % 10)]) {
1316 						b2Vertices.push(new b2Vec2(vertex.x*mInverseMeterToPixelScale, vertex.y*mInverseMeterToPixelScale));
1317 						count++;
1318 					}
1319 					shape.SetAsArray(b2Vertices, b2Vertices.length);
1320 					break;
1321 			}
1322 
1323 			fixture = new b2FixtureDef();
1324 			fixture.shape = shape;
1325 			fixture.restitution = iShape.restitution;
1326 			fixture.friction = iShape.friction;
1327 			fixture.isSensor = iShape.isSensor;
1328 
1329 			//Set this entity's categoryBits, first checking to see if this collision category is a new one
1330 			if(!mCollisionCategories[iShape.collisionCategory]) {
1331 				mCollisionCategories[iShape.collisionCategory] = mNextCollisionBit;
1332 				mNextCollisionBit<<=1;
1333 			}
1334 			fixture.filter.categoryBits = mCollisionCategories[iShape.collisionCategory];
1335 
1336 			//Set this entity's maskBits, first checking to see if any of the collision categories are new
1337 			var collidesWith = iShape.collidesWith;
1338 			for(var category in collidesWith) {
1339 				fixture.filter.maskBits = 0;
1340 				if(!mCollisionCategories[collidesWith[category]]) {
1341 					if (mNextCollisionBit <= 0) {
1342 						throw "Something bad is happening in box2dwebadapter!";
1343 					}
1344 					mCollisionCategories[collidesWith[category]] = mNextCollisionBit;
1345 					mNextCollisionBit<<=1;
1346 				}
1347 				fixture.filter.maskBits |= mCollisionCategories[collidesWith[category]];
1348 			}
1349 
1350 			fixture.density = iShape.density*0.001*mMeterToPixelScale*mMeterToPixelScale; //The density received is in grams per "square pixel", g/px2, but box2D uses kilograms per square meter, kg/m2
1351 
1352 			iBody.CreateFixture(fixture);
1353 		}
1354 
1355 		this.fnCreatePhysicsEntity = function (iAttributes, iGameEntity) {
1356 			var type = iAttributes.physicsType;
1357 			var shapes = iAttributes.physicsShapes;
1358 			var body = new b2BodyDef();
1359 			body.position.Set(iGameEntity.transformation.position.x*mInverseMeterToPixelScale, iGameEntity.transformation.position.y*mInverseMeterToPixelScale);
1360 			body.angle = iGameEntity.transformation.rotation;
1361 			body.fixedRotation = iAttributes.physicsFixedRotation;
1362 			body.angularDamping = iAttributes.physicsAngularDamping;
1363 			body.linearDamping = iAttributes.physicsLinearDamping;
1364 			body.allowSleep = iAttributes.physicsAllowSleep;
1365 			body.bullet = iAttributes.physicsIsBullet;
1366 			body.active = iAttributes.physicsIsActive;
1367 
1368 			//Associate this physics body with the game entity, so we can know which game entity should receive a callback when the physics body collides.
1369 			body.userData = iGameEntity.id;
1370 
1371 			switch (type) {
1372 				case 'static':
1373 					body.type = b2Body.b2_staticBody;
1374 					break;
1375 				case 'dynamic':
1376 					body.type = b2Body.b2_dynamicBody;
1377 					break;
1378 				case 'kinematic':
1379 					body.type = b2Body.b2_kinematicBody;
1380 					break;
1381 			}
1382 
1383 			//Create the physicsbody in the world
1384 			body = mWorld.CreateBody(body);
1385 
1386 			for(var i in shapes) {
1387 				mfnAddShapeToBody(body, shapes[i]);
1388 			}
1389 
1390 			mBodyPairs[iGameEntity.id] = {
1391 				gameEntity: iGameEntity,
1392 				physicsBody: body
1393 			};
1394 		}
1395 		this.fnRemovePhysicsEntity = function (iEntityID) {
1396 			mWorld.DestroyBody(mBodyPairs[iEntityID].physicsBody);
1397 			delete mBodyPairs[iEntityID];
1398 		}
1399 		this.fnRender = function (iContext) {
1400 			if (!iContext || !mWorld) {
1401 				return;
1402 			}
1403 
1404 			var debugDraw = new b2DebugDraw();
1405 			debugDraw.SetSprite(iContext);
1406 			debugDraw.SetDrawScale(mMeterToPixelScale);
1407 			debugDraw.SetFillAlpha(0.0);
1408 			debugDraw.SetLineThickness(1.0);
1409 			debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
1410 			mWorld.SetDebugDraw(debugDraw);
1411 			mWorld.DrawDebugData();
1412 		}
1413 		this.fnUpdate = function (iTimeStep, iIterations) {
1414 			if (mWorld) {
1415 				mWorld.Step(iTimeStep, iIterations, iIterations);
1416 				mfnUpdateGameEntities();
1417 				mWorld.ClearForces();
1418 			}
1419 		}
1420 		this.fnSetGravity = function (iX, iY) {
1421 			mWorld.SetGravity(new b2Vec2(iX*mInverseMeterToPixelScale, iY*mInverseMeterToPixelScale));
1422 		}
1423 		this.fnApplyImpulseAt = function (iEntityID, iPosition, iImpulse) {
1424 			mBodyPairs[iEntityID].physicsBody.ApplyImpulse(new b2Vec2(iImpulse.x*mInverseMeterToPixelScale, iImpulse.y*mInverseMeterToPixelScale), new b2Vec2(iPosition.x*mInverseMeterToPixelScale, iPosition.y*mInverseMeterToPixelScale));
1425 		}
1426 		this.fnSetPhysicsEntityPosition = function (iEntityID, iX, iY) {
1427 			mBodyPairs[iEntityID].physicsBody.SetPosition(new b2Vec2(iX*mInverseMeterToPixelScale, iY*mInverseMeterToPixelScale));
1428 		}
1429 		this.fnSetPhysicsEntityRotation = function (iEntityID, iRotation) {
1430 			mBodyPairs[iEntityID].physicsBody.SetAngle(iRotation);
1431 		}
1432 		this.fnSetPhysicsEntityLinearVelocity = function (iEntityID, iX, iY) {
1433 			mBodyPairs[iEntityID].physicsBody.SetLinearVelocity(new b2Vec2(iX*mInverseMeterToPixelScale, iY*mInverseMeterToPixelScale));
1434 		}
1435 		this.fnGetPhysicsEntityLinearVelocity = function (iEntityID) {
1436 			var v = mBodyPairs[iEntityID].physicsBody.GetLinearVelocity();
1437 			return new Vector2(v.x * mMeterToPixelScale, v.y * mMeterToPixelScale);
1438 		}
1439 		this.fnSetPhysicsEntityAngularVelocity = function (iEntityID, iOmega) {
1440 			mBodyPairs[iEntityID].physicsBody.SetAngularVelocity(iOmega);
1441 		}
1442 		this.fnGetPhysicsEntityAngularVelocity = function (iEntityID) {
1443 			return mBodyPairs[iEntityID].physicsBody.GetAngularVelocity();
1444 		}
1445 		this.fnGetCenterOfMass = function (iEntityID) {
1446 			var com = mBodyPairs[iEntityID].physicsBody.GetWorldCenter();
1447 			return new Vector2(com.x*mMeterToPixelScale, com.y*mMeterToPixelScale);
1448 		}
1449 		this.fnGetCollisionCategoryArray = function () {
1450 			var result = [];
1451 			for(var category in mCollisionCategories) {
1452 				result.push(category);
1453 			}
1454 			return result;
1455 		}
1456 		this.fnSetPhysicsType = function (iEntityID, iType) {
1457 			body = mBodyPairs[iEntityID].physicsBody;
1458 			switch (iType) {
1459 				case 'static':
1460 					body.SetType(b2Body.b2_staticBody);
1461 					break;
1462 				case 'dynamic':
1463 					body.SetType(b2Body.b2_dynamicBody);
1464 					break;
1465 				case 'kinematic':
1466 					body.SetType(b2Body.b2_kinematicBody);
1467 					break;
1468 			}
1469 		}
1470 		this.fnAddShapeToEntity = function (iEntityID, iShape) {
1471 			mfnAddShapeToBody(mBodyPairs[iEntityID].physicsBody, iShape);
1472 		}
1473 		this.fnRemoveAllShapesFromEntity = function (iEntityID) {
1474 			var body = mBodyPairs[iEntityID].physicsBody;
1475 			var fixture = body.GetFixtureList();
1476 			while(fixture) {
1477 				var temp = fixture;
1478 				fixture = fixture.GetNext();
1479 				body.DestroyFixture(temp);
1480 			}
1481 		}
1482 		this.fnSetPhysicsEntityFixedRotation = function (iEntityID, iFixed) {
1483 			mBodyPairs[iEntityID].physicsBody.SetFixedRotation(iFixed);
1484 		}
1485 		this.fnSetPhysicsEntityActive = function (iEntityID, iActive) {
1486 			mBodyPairs[iEntityID].physicsBody.SetActive(iActive);
1487 		}
1488 		this.fnOnLevelUnloaded = function () {
1489 			mWorld = null;
1490 		}
1491 		this.fnRayCastOne = function (iRayStartX, iRayStartY, iRayEndX, iRayEndY) {
1492 			var hitFixture = mWorld.RayCastOne(new b2Vec2(iRayStartX*mInverseMeterToPixelScale, iRayStartY*mInverseMeterToPixelScale), new b2Vec2(iRayEndX*mInverseMeterToPixelScale, iRayEndY*mInverseMeterToPixelScale));
1493 			if (hitFixture) {
1494 				return mBodyPairs[hitFixture.GetBody().GetUserData()].gameEntity;
1495 			}
1496 			return null;
1497 		}
1498 		this.fnRayCastAll = function (iRayStartX, iRayStartY, iRayEndX, iRayEndY) {
1499 			var result = [];
1500 			var array = mWorld.RayCastAll(new b2Vec2(iRayStartX*mInverseMeterToPixelScale, iRayStartY*mInverseMeterToPixelScale), new b2Vec2(iRayEndX*mInverseMeterToPixelScale, iRayEndY*mInverseMeterToPixelScale));
1501 			var len = array.length;
1502 			for (var i = 0; i < len; i ++) {
1503 				result[i] = mBodyPairs[array[i].GetBody().GetUserData()].gameEntity;
1504 			}
1505 			return result;
1506 		}
1507 	}
1508 })();
1509 (function () {
1510 	var Message = VENISON.MESSAGES.Message;
1511 	var MessageManager = VENISON.MESSAGES.MessageManager;
1512 	var EntityManager = VENISON.ENTITY.EntityManager;
1513 	/**
1514 	 * @class Singleton used to update and communicate with the physics engine.
1515 	 */
1516 	VENISON.PHYSICS.PhysicsManager = new function () {
1517 		var mPhysicsEngine = new VENISON.PHYSICS.Box2dwebAdapter();
1518 		var mGravity = new VENISON.UTILITIES.Vector2();
1519 		/**
1520 		 * The number of iterations to use for the physics update.
1521 		 * @fieldOf VENISON.PHYSICS.PhysicsManager.prototype
1522 		 * @name iterations
1523 		 * @default 10
1524 		 * @type Number
1525 		 */
1526 		this.iterations = 10;
1527 		/**
1528 		 * Set to true if physics debug info should be drawn.
1529 		 * @fieldOf VENISON.PHYSICS.PhysicsManager.prototype
1530 		 * @name renderDebugInfo
1531 		 * @default false
1532 		 * @type Boolean
1533 		 */
1534 		this.renderDebugInfo = false;
1535 		/**
1536 		 * Tell the physics engine to create a physics entity. Called internally from PhysicsProperty.
1537 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1538 		 * @name fnCreatePhysicsEntity
1539 		 * @param {Object} iAttributes The attributes to use for the physics engine.
1540 		 * @param {VENISON.ENTITY.GameEntity} iGameEntity The game entity that wants to create a physics entity.
1541 		 * @ignore
1542 		 */
1543 		this.fnCreatePhysicsEntity = function (iAttributes, iGameEntity) {
1544 			mPhysicsEngine.fnCreatePhysicsEntity(iAttributes, iGameEntity);
1545 		}
1546 		/**
1547 		 * Tell the physics engine to remove a physics entity. Called internally from PhysicsProperty.
1548 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1549 		 * @name fnRemovePhysicsEntity
1550 		 * @param {Number} iEntityID The ID of the entity that owns this physics entity.
1551 		 * @ignore
1552 		 */
1553 		this.fnRemovePhysicsEntity = function (iEntityID) {
1554 			mPhysicsEngine.fnRemovePhysicsEntity(iEntityID);
1555 		}
1556 		/**
1557 		 * Tell the physics engine to update the game physics.
1558 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1559 		 * @param {Number} iTimeStep The time step.
1560 		 * @ignore
1561 		 */
1562 		this.fnUpdate = function (iTimeStep) {
1563 			mPhysicsEngine.fnUpdate(iTimeStep, this.iterations);
1564 		}
1565 		/**
1566 		 * Tell the physics engine to render physics information.
1567 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1568 		 * @param {Object} iContext The 2D rendering context of the canvas to draw on.
1569 		 * @ignore
1570 		 */
1571 		this.fnRender = function (iContext) {
1572 			iContext.save();
1573 			mPhysicsEngine.fnRender(iContext);
1574 			iContext.restore();
1575 		}
1576 		/**
1577 		 * Tell the physics engine to initialize itself. Called internally from the LevelLoader.
1578 		 * NOTE: iLeft, iTop, iWidth and iHeight are only used if the physics engine doesn't support an infinite physics world.
1579 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1580 		 * @name fnInitialize
1581 		 * @param {Number} iLeft The far left of the world.
1582 		 * @param {Number} iTop The top of the world.
1583 		 * @param {Number} iWidth The width of the world.
1584 		 * @param {Number} iHeight The height of the world.
1585 		 * @param {Number} iGravityX The horizontal component of the gravity vector.
1586 		 * @param {Number} iGravityY The vertical component of the gravity vector.
1587 		 * @ignore
1588 		 */
1589 		this.fnInitialize = function (iLeft, iTop, iWidth, iHeight, iGravityX, iGravityY) {
1590 			mGravity.x = iGravityX;
1591 			mGravity.y = iGravityY;
1592 			mPhysicsEngine.fnInitialize(iLeft, iTop, iWidth, iHeight, iGravityX, iGravityY);
1593 		}
1594 		/**
1595 		 * Get the gravity vector.
1596 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1597 		 * @name fnGetGravity
1598 		 * @returns {VENISON.UTILITIES.Vector2} The current world gravity. Remember that positive y is downwards!
1599 		 */
1600 		this.fnGetGravity = function () {
1601 			return mGravity;
1602 		}
1603 		/**
1604 		 * Set the gravity vector and tell the physics engine of the update.
1605 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1606 		 * @name fnSetGravity
1607 		 * @param {Number} iX The horizontal component of the gravity vector.
1608 		 * @param {Number} iY The vertical component of the gravity vector.
1609 		 */
1610 		this.fnSetGravity = function (iX, iY) {
1611 			mGravity.x = iX;
1612 			mGravity.y = iY;
1613 			mPhysicsEngine.fnSetGravity(iX, iY);
1614 		}
1615 		/**
1616 		 * Tell the physics engine to apply an impulse at a position on an entity.
1617 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1618 		 * @name fnApplyImpulseAt
1619 		 * @param {Number} iEntityID The ID of the entity to give an impulse.
1620 		 * @param {Object} iPosition An object with x and y properties describing the position in world space where the impulse should be applied.
1621 		 * @param {Object} iImpulse An object with x and y properties describing the impulse to apply.
1622 		 */
1623 		this.fnApplyImpulseAt = function (iEntityID, iPosition, iImpulse) {
1624 			mPhysicsEngine.fnApplyImpulseAt(iEntityID, iPosition, iImpulse);
1625 		}
1626 		/**
1627 		 * Tell the physics engine to set the position of a physics entity. Called internally from PhysicsProperty as a reaction to a received 'setPosition' message
1628 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1629 		 * @name fnSetPhysicsEntityPosition
1630 		 * @param {Number} iEntityID The ID of the entity that owns the physics entity.
1631 		 * @param {Number} iX The x coordinate in world space.
1632 		 * @param {Number} iY The y coordinate in world space.
1633 		 * @ignore
1634 		 */
1635 		this.fnSetPhysicsEntityPosition = function (iEntityID, iX, iY) {
1636 			mPhysicsEngine.fnSetPhysicsEntityPosition(iEntityID, iX, iY);
1637 		}
1638 		/**
1639 		 * Tell the physics engine to set the angle (not the angular velocity - for that, use fnSetPhysicsEntityAngularVelocity()) of a physics entity. Called internally from PhysicsProperty as a reaction to a received 'setRotation' message
1640 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1641 		 * @name fnSetPhysicsEntityRotation
1642 		 * @param {Number} iEntityID The ID of the entity that owns the physics entity.
1643 		 * @param {Number} iRotation The rotation in radians.
1644 		 * @ignore
1645 		 */
1646 		this.fnSetPhysicsEntityRotation = function (iEntityID, iRotation) {
1647 			mPhysicsEngine.fnSetPhysicsEntityRotation(iEntityID, iRotation);
1648 		}
1649 		/**
1650 		 * Tell the physics engine to set the linear velocity of a physics entity. Called internally from PhysicsProperty as a reaction to a received 'setLinearVelocity' message
1651 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1652 		 * @name fnSetPhysicsEntityLinearVelocity
1653 		 * @param {Number} iEntityID The ID of the entity that owns the physics entity.
1654 		 * @param {Number} iX The horizontal component of the velocity, in pixels per second.
1655 		 * @param {Number} iY The vertical component of the velocity, in pixels per second.
1656 		 * @ignore
1657 		 */
1658 		this.fnSetPhysicsEntityLinearVelocity = function (iEntityID, iX, iY) {
1659 			mPhysicsEngine.fnSetPhysicsEntityLinearVelocity(iEntityID, iX, iY);
1660 		}
1661 		/**
1662 		 * Get the linear velocity of an entity.
1663 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1664 		 * @name fnGetPhysicsEntityLinearVelocity
1665 		 * @param {Number} iEntityID The ID of the entity.
1666 		 * @returns {VENISON.UTILITIES.Vector2} The linear velocity of the entity with ID iID, in pixels per second.
1667 		 */
1668 		this.fnGetPhysicsEntityLinearVelocity = function (iEntityID) {
1669 			return mPhysicsEngine.fnGetPhysicsEntityLinearVelocity(iEntityID);
1670 		}
1671 		/**
1672 		 * Tell the physics engine to set the angular velocity of a physics entity. Called internally from PhysicsProperty as a reaction to a received 'setAngularVelocity' message
1673 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1674 		 * @name fnSetPhysicsEntityAngularVelocity
1675 		 * @param {Number} iEntityID The ID of the entity that owns the physics entity.
1676 		 * @param {Number} iOmega The new angular velocity, in radians per second.
1677 		 * @ignore
1678 		 */
1679 		this.fnSetPhysicsEntityAngularVelocity = function (iEntityID, iOmega) {
1680 			mPhysicsEngine.fnSetPhysicsEntityAngularVelocity(iEntityID, iOmega);
1681 		}
1682 		/**
1683 		 * Get the angular velocity of an entity.
1684 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1685 		 * @name fnGetPhysicsEntityAngularVelocity
1686 		 * @param {Number} iEntityID The ID of the entity.
1687 		 * @returns {Number} The angular velocity of the entity with ID iID, in radians per seconds.
1688 		 */
1689 		this.fnGetPhysicsEntityAngularVelocity = function (iEntityID) {
1690 			return mPhysicsEngine.fnGetPhysicsEntityAngularVelocity(iEntityID);
1691 		}
1692 		/**
1693 		 * Get the entitys center of mass.
1694 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1695 		 * @name fnGetCenterOfMass
1696 		 * @param {VENISON.UTILITIES.Vector2} iEntityID The ID of the entity.
1697 		 * @returns {VENISON.UTILITIES.Vector2} The center of mass of the entity with ID iID.
1698 		 */
1699 		this.fnGetCenterOfMass = function (iEntityID) {
1700 			return mPhysicsEngine.fnGetCenterOfMass(iEntityID);
1701 		}
1702 		/**
1703 		 * Called from the physics engine on contact events. Sends messages to the entities involved in the contact.
1704 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1705 		 * @param {Number} iEntityIDa The ID of the first entity involved in the contact.
1706 		 * @param {Number} iEntityIDb The ID of the second entity involved in the contact.
1707 		 * @param {VENISON.UTILITIES.Vector2} iContactPosition The contact position.
1708 		 * @param {VENISON.UTILITIES.Vector2} iContactNormal The contact normal.
1709 		 * @param {String} iType The type of the contact event.
1710 		 * @returns {Boolean} true if the event type is preSolve and the contact should be disabled.
1711 		 * @ignore
1712 		 */
1713 		this.fnNotifyGameEntitiesOfContactEvent = function (iEntityIDa, iEntityIDb, iContactPosition, iContactNormal, iType) {
1714 			var msgType;
1715 			switch (iType) {
1716 				case 'begin':
1717 					msgType = 'physicsOnContactBegin';
1718 					break;
1719 				case 'end':
1720 					msgType = 'physicsOnContactEnd';
1721 					break;
1722 				case 'postSolve':
1723 					msgType = 'physicsOnContactPostSolve';
1724 					break;
1725 				case 'preSolve':
1726 					msgType = 'physicsOnContactPreSolve';
1727 					break;
1728 			}
1729 			var message = new Message(msgType);
1730 			message.content = {
1731 				contactPosition: iContactPosition
1732 			};
1733 
1734 			var shouldDisableContact = false;
1735 
1736 			if(EntityManager.fnGetEntityByID(iEntityIDa)) {
1737 				message.content.collideeID = iEntityIDb;
1738 				message.content.contactNormal = iContactNormal;
1739 				message.to = iEntityIDa;
1740 
1741 				MessageManager.fnSendMessage(message);
1742 				shouldDisableContact = (true === message.content.disableContact); //Only used for preSolve
1743 			}
1744 			if(EntityManager.fnGetEntityByID(iEntityIDb)) {
1745 				message.content.collideeID = iEntityIDa;
1746 				message.content.contactNormal = iContactNormal.fnMultiplyScalar(-1);
1747 				message.to = iEntityIDb;
1748 
1749 				MessageManager.fnSendMessage(message);
1750 				shouldDisableContact |= (true === message.content.disableContact);//Only used for preSolve
1751 			}
1752 			return shouldDisableContact; //Only used for preSolve
1753 		}
1754 		/**
1755 		 * Get the array of collision categories.
1756 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1757 		 * @name fnGetCollisionCategoryArray
1758 		 * @returns {Array} The array of all collision categories currently in use by the physics engine represented as strings.
1759 		 */
1760 		this.fnGetCollisionCategoryArray = function () {
1761 			return mPhysicsEngine.fnGetCollisionCategoryArray();
1762 		}
1763 		/**
1764 		 * Tell the physics engine to set the physics type of a physics entity. Called internally from PhysicsProperty as a reaction to a received 'setPhysicsType' message
1765 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1766 		 * @name fnSetPhysicsType
1767 		 * @param {Number} iEntityID The ID of the entity that owns the physics entity.
1768 		 * @param {String} iType The physics type.
1769 		 * @ignore
1770 		 */
1771 		this.fnSetPhysicsType = function (iEntityID, iType) {
1772 			mPhysicsEngine.fnSetPhysicsType(iEntityID, iType);
1773 		}
1774 		/**
1775 		 * Currently never used, and may not work as intended.
1776 		 * Tell the physics engine to add a shape to the physics entity.
1777 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1778 		 * @name fnAddShapeToEntity
1779 		 * @param {Number} iEntityID The ID of the entity that owns the physics entity.
1780 		 * @param {Object} iShape The shape to add.
1781 		 * @ignore
1782 		 */
1783 		this.fnAddShapeToEntity = function (iEntityID, iShape) {
1784 			mPhysicsEngine.fnAddShapeToEntity(iEntityID, iShape);
1785 		}
1786 		/**
1787 		 * Currently never used, and may not work as intended.
1788 		 * Tell the physics engine to remove all shapes from the physics entity.
1789 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1790 		 * @name fnRemoveAllShapesFromEntity
1791 		 * @param {Number} iEntityID The ID of the entity that owns the physics entity.
1792 		 * @ignore
1793 		 */
1794 		this.fnRemoveAllShapesFromEntity = function (iEntityID) {
1795 			mPhysicsEngine.fnRemoveAllShapesFromEntity(iEntityID);
1796 		}
1797 		/**
1798 		 * Tell the physics engine to lock or unlock the rotation of the physics entity. Called internally from PhysicsProperty as a reaction to a received 'setFixedRotation' message
1799 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1800 		 * @name fnSetPhysicsEntityFixedRotation
1801 		 * @param {Number} iEntityID The ID of the entity that owns the physics entity.
1802 		 * @param {Boolean} iFixed true if the rotation should be fixed, false if it should not.
1803 		 * @ignore
1804 		 */
1805 		this.fnSetPhysicsEntityFixedRotation = function (iEntityID, iFixed) {
1806 			mPhysicsEngine.fnSetPhysicsEntityFixedRotation(iEntityID, iFixed);
1807 		}
1808 		/**
1809 		 * Tell the physics engine to set wheter a physics entity is active. Called internally from PhysicsProperty as a reaction to a received 'setActive' message
1810 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1811 		 * @name fnSetPhysicsEntityActive
1812 		 * @param {Number} iEntityID The ID of the entity that owns the physics entity.
1813 		 * @param {Boolean} iActive true if the entity should be active and take part of the physics simulation, false if not.
1814 		 * @ignore
1815 		 */
1816 		this.fnSetPhysicsEntityActive = function (iEntityID, iActive) {
1817 			mPhysicsEngine.fnSetPhysicsEntityActive(iEntityID, iActive);
1818 		}
1819 		/**
1820 		 * Give the physics engine a chance to do stuff when the level is unloaded.
1821 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1822 		 * @ignore
1823 		 */
1824 		this.fnOnLevelUnloaded = function () {
1825 			mPhysicsEngine.fnOnLevelUnloaded();
1826 		}
1827 		/**
1828 		 * Get the first entity that is hit by a ray.
1829 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1830 		 * @name fnRayCastOne
1831 		 * @param {Number} iRayStartX The x-value of the starting point of the ray.
1832 		 * @param {Number} iRayStartY The y-value of the starting point of the ray.
1833 		 * @param {Number} iRayEndX The x-value of the end point of the ray.
1834 		 * @param {Number} iRayEndY The y-value of the end point of the ray.
1835 		 * @returns {VENISON.ENTITY.GameEntity} The first physically enabled (that is, it has a PhysicProperty, at least one physics shape and is active in the physics simulation) game entity that the ray hits.
1836 		 */
1837 		this.fnRayCastOne = function (iRayStartX, iRayStartY, iRayEndX, iRayEndY) {
1838 			return mPhysicsEngine.fnRayCastOne(iRayStartX, iRayStartY, iRayEndX, iRayEndY);
1839 		}
1840 		/**
1841 		 * Get an array with all entities that are hit by a ray.
1842 		 * @methodOf VENISON.PHYSICS.PhysicsManager.prototype
1843 		 * @name fnRayCastAll
1844 		 * @param {Number} iRayStartX The x-value of the starting point of the ray.
1845 		 * @param {Number} iRayStartY The y-value of the starting point of the ray.
1846 		 * @param {Number} iRayEndX The x-value of the end point of the ray.
1847 		 * @param {Number} iRayEndY The y-value of the end point of the ray.
1848 		 * @returns {Array} All physically enabled (that is, it has a PhysicProperty, at least one physics shape and is active in the physics simulation) game entities that the ray hits.
1849 		 * @see VENISON.ENTITY.GameEntity
1850 		 */
1851 		this.fnRayCastAll = function (iRayStartX, iRayStartY, iRayEndX, iRayEndY) {
1852 			return mPhysicsEngine.fnRayCastAll(iRayStartX, iRayStartY, iRayEndX, iRayEndY);
1853 		}
1854 	}
1855 })();
1856 //Real Time Collision Detection, Christer Ericson, 2005, p. 300ff
1857 (function() {
1858 	var NUM_BUCKETS = 1024;
1859 	var SPHERE_TO_CELL_RATIO = 1 / 4; // Largest sphere in cell is 1/4 of the cell size
1860 	var CELL_TO_CELL_RATIO = 2;
1861 	var MIN_CELL_SIZE = 30;
1862 	var EPSILON = 0.01; //?
1863 	/**
1864 	 * Used to compute the hash bucket index for an object.
1865 	 * See "Real Time Collision Detection", Christer Ericson, 2005, p. 288.
1866 	 * @function
1867 	 * @param {Number} iX The objects position at the current level.
1868 	 * @param {Number} iY The objects position at the current level.
1869 	 * @param {Number} iLayer The smallest level where the object fits.
1870 	 * @returns {Number} The computed hash bucket index.
1871 	 * @ignore
1872 	 */
1873 	function gfnComputeHashBucketIndex(iX, iY, iLayer) {
1874 		var h1 = 0x8da6b343;
1875 		var h2 = 0xd8163841;
1876 		var h3 = 0xcb1ab31f;
1877 
1878 		var n = h1 * iX + h2 * iY + h3 * iLayer;
1879 		n = n % NUM_BUCKETS;
1880 		if (n < 0) { //Modulo bug?
1881 			n += NUM_BUCKETS;
1882 		}
1883 		return n;
1884 	}
1885 
1886 	/**
1887 	 * An object in the hgrid.
1888 	 * @class
1889 	 * @ignore
1890 	 */
1891 	VENISON.GRAPHICS.HGridObject = function() {
1892 		this.nextObject = null; //A pointer to the next object
1893 		this.prevObject = null;
1894 		this.bucket = -1; //Index of hash bucket object
1895 		this.level = -1; //Level of this object in the hierarchy
1896 		this.entity = null;
1897 		this.radius = null;
1898 	}
1899 	/**
1900 	 * Hierarchical grid data structure that we use for the viewport culling.
1901 	 * See Real Time Collision Detection, Christer Ericson, 2005, p. 300ff
1902 	 * @class
1903 	 * @ignore
1904 	 */
1905 	VENISON.GRAPHICS.HGrid = function() {
1906 		this.occupiedLevelsMask = 0x0000;
1907 		this.objectsAtLevel = [];
1908 		this.objectBucket = [];
1909 		this.objectBucket.length = NUM_BUCKETS; //Allocate the maximum memory already
1910 		this.timeStamp = [];
1911 		this.timeStamp.length = NUM_BUCKETS; //Allocate the maximum memory already
1912 		this.tick = 0;
1913 		/**
1914 		 * Insert an hgrid object into the hgrid.
1915 		 * @function
1916 		 * @param {VENISON.GRAPHICS.HGridObject} iHGridObject
1917 		 */
1918 		this.fnInsertObj = function(iHGridObject) {
1919 			var level;
1920 			var size = MIN_CELL_SIZE;
1921 			var entity = iHGridObject.entity;
1922 			var entityTransform = entity.transformation;
1923 			var diameter = iHGridObject.radius * 2;
1924 
1925 			for (level = 0; size * SPHERE_TO_CELL_RATIO < diameter; level++) {
1926 				size *= CELL_TO_CELL_RATIO;
1927 			}
1928 
1929 			var bucket = gfnComputeHashBucketIndex(Math.floor(entityTransform.position.x / size), Math.floor(entityTransform.position.y / size), level);
1930 			iHGridObject.bucket = bucket;
1931 			iHGridObject.level = level;
1932 
1933 			//Insert the physics entity into the double linked list
1934 			if (this.objectBucket[bucket]) {
1935 				iHGridObject.nextObject = this.objectBucket[bucket];
1936 				this.objectBucket[bucket].prevObject = iHGridObject;
1937 			}
1938 			this.objectBucket[bucket] = iHGridObject;
1939 
1940 			if (!this.objectsAtLevel[level]) {
1941 				this.objectsAtLevel[level] = 0;
1942 			}
1943 			this.objectsAtLevel[level]++;
1944 			this.occupiedLevelsMask |= (1 << level);
1945 		}
1946 		/**
1947 		 * Remove an object from the hgrid.
1948 		 * @function
1949 		 * @param {VENISON.GRAPHICS.HGridObject} iHGridObject
1950 		 */
1951 		this.fnRemoveObj = function(iHGridObject) {
1952 			if (this.objectsAtLevel[iHGridObject.level] === 0) {
1953 				throw "Failed to remove object from hgrid!";
1954 			}
1955 
1956 			//Decrease the number of objects at this level. If the number reaches zero, there are no objects left on the level.
1957 			if (--this.objectsAtLevel[iHGridObject.level] === 0) {
1958 				this.occupiedLevelsMask &= ~ (1 << iHGridObject.level);
1959 			}
1960 
1961 			var prevObj = iHGridObject.prevObject;
1962 			var nextObj = iHGridObject.nextObject;
1963 
1964 			if (this.objectBucket[iHGridObject.bucket] === iHGridObject) {
1965 				this.objectBucket[iHGridObject.bucket] = nextObj;
1966 			}
1967 
1968 			if (prevObj) {
1969 				prevObj.nextObject = nextObj;
1970 			}
1971 			if (nextObj) {
1972 				nextObj.prevObject = prevObj;
1973 			}
1974 
1975 			iHGridObject.prevObject = null;
1976 			iHGridObject.nextObject = null;
1977 
1978 		}
1979 		/**
1980 		 * Used to check an object against the hgrid for potential collisions.
1981 		 * @function
1982 		 * @param {Object} iPosition The midpoint of the circle.
1983 		 * @param {Number} iRadius The radius of the circle.
1984 		 * @param {Function} iCallbackFunction The function that will be called back for each Entity in the GameEntity that the given circle overlaps, with the current GameEntity passed as the argument.
1985 		 */
1986 		this.fnCheckCircleAgainstGrid = function(iPosition, iRadius, iCallbackFunction) {
1987 			var size = MIN_CELL_SIZE;
1988 			var startLevel = 0;
1989 			var occupiedLevelsMask = this.occupiedLevelsMask;
1990 
1991 			this.tick++;
1992 			var objectsAtLevelLength = this.objectsAtLevel.length;
1993 			for (var level = startLevel; level < objectsAtLevelLength; size *= CELL_TO_CELL_RATIO, occupiedLevelsMask >>= 1, level++) {
1994 				//If no objects in rest of grid, stop now
1995 				if (occupiedLevelsMask === 0) {
1996 					break;
1997 				}
1998 
1999 				//If no objects at this level, go to the next level
2000 				if ((occupiedLevelsMask & 1) === 0) {
2001 					continue;
2002 				}
2003 
2004 				var delta = iRadius + size * SPHERE_TO_CELL_RATIO + EPSILON;
2005 				var ooSize = 1 / size;
2006 				var x1 = Math.floor((iPosition.x - delta) * ooSize);
2007 				var y1 = Math.floor((iPosition.y - delta) * ooSize);
2008 				var x2 = Math.ceil((iPosition.x + delta) * ooSize);
2009 				var y2 = Math.ceil((iPosition.y + delta) * ooSize);
2010 
2011 				//Check overlapped grid cells
2012 				for (var x = x1; x <= x2; x++) {
2013 					for (var y = y1; y <= y2; y++) {
2014 
2015 						var bucket = gfnComputeHashBucketIndex(x, y, level);
2016 
2017 						if (this.timeStamp[bucket] === this.tick) {
2018 							continue;
2019 						}
2020 						this.timeStamp[bucket] = this.tick;
2021 
2022 						var other = this.objectBucket[bucket];
2023 						while (other) {
2024 							var distX = iPosition.x - other.entity.transformation.position.x;
2025 							var distY = iPosition.y - other.entity.transformation.position.y;
2026 							var distSquared = distX * distX + distY * distY;
2027 							if (distSquared <= Math.pow(iRadius + other.radius + EPSILON, 2)) {
2028 								iCallbackFunction(other.entity);
2029 							}
2030 							other = other.nextObject;
2031 						}
2032 					}
2033 				}
2034 			}
2035 		}
2036 	}
2037 })();
2038 (function() {
2039 	var Vector2 = VENISON.UTILITIES.Vector2;
2040 	//The Graphics Manager global singleton object
2041 	/**
2042 	 * @class Singleton used for updating the graphics.
2043 	 */
2044 	VENISON.GRAPHICS.GraphicsManager = new function() {
2045 		//private
2046 		var mHGrid = new VENISON.GRAPHICS.HGrid();
2047 		var mEntitiesByLayer = []; //An array containing arrays. Includes all entities that has a GraphicsProperty
2048 		var mCameras = {}; //The dictionary of cameras
2049 		//public
2050 		/**
2051 		 * The update function that draws everything. Should not be called explicitly.
2052 		 * @methodOf VENISON.GRAPHICS.GraphicsManager.prototype
2053 		 * @name fnUpdate
2054 		 * @ignore
2055 		 */
2056 		this.fnUpdate = function() {
2057 			for (var name in mCameras) {
2058 				mCameras[name].fnUpdate();
2059 			}
2060 		}
2061 		/**
2062 		 * Register a camera with a specific name.
2063 		 * NOTE: If a camera with name iName is already registered, that camera will be overwritten. You have been warned.
2064 		 * @methodOf VENISON.GRAPHICS.GraphicsManager.prototype
2065 		 * @name fnRegisterCameraWithName
2066 		 * @param {VENISON.GRAPHICS.Camera} iCamera The camera to register.
2067 		 * @param {String} iName The name of the camera.
2068 		 */
2069 		this.fnRegisterCameraWithName = function(iCamera, iName) {
2070 			mCameras[iName] = iCamera;
2071 		}
2072 		/**
2073 		 * Get the camera with a specific name.
2074 		 * @methodOf VENISON.GRAPHICS.GraphicsManager.prototype
2075 		 * @name fnGetCameraByName
2076 		 * @param {String} iName The name of the camera.
2077 		 * @returns {VENISON.GRAPHICS.Camera} The camera with name iName.
2078 		 */
2079 		this.fnGetCameraByName = function(iName) {
2080 			return mCameras[iName];
2081 		}
2082 		/**
2083 		 * Register an entity with the VENISON.GRAPHICS.GraphicsManager and place it on the correct layer. Also insert it into the hgrid.
2084 		 * @methodOf VENISON.GRAPHICS.GraphicsManager.prototype
2085 		 * @param {VENISON.GRAPHICS.HGridObject} iHGridObject The object to register. Contains a pointer to the entity.
2086 		 * @ignore
2087 		 */
2088 		this.fnRegisterHGridObject = function(iHGridObject) {
2089 			//Insert the object into the hgrid
2090 			mHGrid.fnInsertObj(iHGridObject);
2091 
2092 			var entity = iHGridObject.entity;
2093 			var entityID = entity.id;
2094 			if (entityID === -1) {
2095 				throw "In GraphicsManager.fnRegisterEntity(): Invalid entity ID! Are you sure the entity is registered with the EntityManager already?";
2096 			}
2097 
2098 			var l = entity.attributes.graphicsLayer + 500; //graphicsLayers go from -500 to 500
2099 			graphicsLayerArray = mEntitiesByLayer[l];
2100 
2101 			//If there is no other entity on the graphicsLayer, the insertion is straight forward.
2102 			if (!graphicsLayerArray || graphicsLayerArray.length === 0) {
2103 				mEntitiesByLayer[l] = [entity];
2104 				return;
2105 			}
2106 
2107 			//Insert the entity correctly into the sorted array
2108 			var i = graphicsLayerArray.length - 1; //The last of the elements in the array
2109 			while (entityID < graphicsLayerArray[i]['id']) {
2110 				graphicsLayerArray[i + 1] = graphicsLayerArray[i];
2111 				i--;
2112 				if (i < 0) {
2113 					break;
2114 				}
2115 			}
2116 			graphicsLayerArray[i + 1] = entity;
2117 
2118 		}
2119 		/**
2120 		 * Remove an entity from the VENISON.GRAPHICS.GraphicsManager. Also remove it from the hgrid.
2121 		 * @methodOf VENISON.GRAPHICS.GraphicsManager.prototype
2122 		 * @param {VENISON.GRAPHICS.HGridObject} iHGridObject The object to remove. Stores a pointer to the entity.
2123 		 * @ignore
2124 		 */
2125 		this.fnRemoveHGridObject = function(iHGridObject) {
2126 			//Remove the object from the hgrid
2127 			mHGrid.fnRemoveObj(iHGridObject);
2128 
2129 			//Remove the object from the layer array
2130 			var entity = iHGridObject.entity;
2131 			var previousLayer = entity.attributes.graphicsLayer + 500;
2132 			var graphicsLayerArray = mEntitiesByLayer[previousLayer];
2133 			var indexInLayer = VENISON.UTILITIES.gfnFindIndexOfElementWithCertainMemberValue(graphicsLayerArray, 'id', entity.id);
2134 			var graphicsLayerArrayLength = graphicsLayerArray.length - 1;
2135 			for (var i = indexInLayer; i < graphicsLayerArrayLength; i++) {
2136 				graphicsLayerArray[i] = graphicsLayerArray[i + 1];
2137 			}
2138 			graphicsLayerArray.pop(); //Truncate the last element
2139 		}
2140 		/**
2141 		 * Remove the object from the hgrid and then insert it again, since it may have moved since the last frame.
2142 		 * @methodOf VENISON.GRAPHICS.GraphicsManager.prototype
2143 		 * @param {VENISON.GRAPHICS.HGridObject} iHGridObject The object to update.
2144 		 * @ignore
2145 		 */
2146 		this.fnUpdateHGridObject = function(iHGridObject) {
2147 			//Remove the object from the hgrid
2148 			mHGrid.fnRemoveObj(iHGridObject);
2149 			//Insert the object into the hgrid
2150 			mHGrid.fnInsertObj(iHGridObject);
2151 		}
2152 		/**
2153 		 * Get all the entities registered within the GraphicsManager.
2154 		 * @methodOf VENISON.GRAPHICS.GraphicsManager.prototype
2155 		 * @name fnGetEntities
2156 		 * @returns {Array} An array of arrays representing all the layers and the entities on them.
2157 		 */
2158 		this.fnGetEntities = function() {
2159 			return mEntitiesByLayer;
2160 		}
2161 		/**
2162 		 * Set the layer of an entity.
2163 		 * NOTE: Called by the VENISON.PROPERTIES.GraphicsProperty, don't call explicitly.
2164 		 * @methodOf VENISON.GRAPHICS.GraphicsManager.prototype
2165 		 * @param {VENISON.GRAPHICS.HGridObject} iHGridObject The object to change layer of. Stores a pointer to the entity.
2166 		 * @param {Number} iNewLayer The layer. Between -500 and 500.
2167 		 * @ignore
2168 		 */
2169 		this.fnSetLayerOfHGridObject = function(iHGridObject, iNewLayer) {
2170 			var entity = iHGridObject.entity;
2171 			var previousLayer = entity.attributes.graphicsLayer + 500;
2172 			iNewLayer += 500;
2173 			if (iNewLayer === previousLayer) {
2174 				return; //No need to change anything if no change is needed =)
2175 			}
2176 
2177 			//Remove the entity from the previous graphicsLayer
2178 			this.fnRemoveHGridObject(iHGridObject);
2179 
2180 			//Correct the graphicsLayer attribute
2181 			entity.attributes.graphicsLayer = iNewLayer - 500;
2182 
2183 			//Add the entity to the new graphicsLayer
2184 			this.fnRegisterHGridObject(iHGridObject);
2185 
2186 		}
2187 		/**
2188 		 * Get the entity on a certain position.
2189 		 * @methodOf VENISON.GRAPHICS.GraphicsManager.prototype
2190 		 * @name fnGetEntityOnPosition
2191 		 * @param {VENISON.UTILITIES.Vector2} iWorldPos The position in world space.
2192 		 * @param {Boolean} iIncludeInvisibles true if invisible entities should be considered.
2193 		 * @returns {VENISON.ENTITY.GameEntity} The topmost (highest graphicsLayer) entity whose graphics covers the world point defined by iWorldPos. null if no entity was found.
2194 		 */
2195 		this.fnGetEntityOnPosition = function(iWorldPos, iIncludeInvisibles) {
2196 			//The brute force way should take O(n) time. Maybe the use of VENISON.GRAPHICS.HGrid could improve performance
2197 			var potentialEntities = [];
2198 			this.fnCheckCircleAgainstGrid(iWorldPos, 1, function (iEntity) {
2199 				potentialEntities[iEntity.id] = true;
2200 			});
2201 			for (var graphicsLayer = mEntitiesByLayer.length - 1; graphicsLayer >= 0; graphicsLayer--) { //Reversed traversal of the layers, in order to find the topmost entity
2202 				if (mEntitiesByLayer[graphicsLayer]) {
2203 					var layerLength = mEntitiesByLayer[graphicsLayer].length;
2204 					for (var i = layerLength - 1; i >= 0; i--) {
2205 						var entity = mEntitiesByLayer[graphicsLayer][i];
2206 						if (!potentialEntities[entity.id] || (!iIncludeInvisibles && !entity.attributes.graphicsVisible)) { //Early out
2207 							continue;
2208 						}
2209 						var position = entity.transformation.position;
2210 						var imageHalfWidth = 0.5 * entity.graphicsImage.width;
2211 						var imageHalfHeight = 0.5 * entity.graphicsImage.height;
2212 
2213 						var objectSpacePos = entity.transformation.fnWorldToLocal(iWorldPos);
2214 
2215 						if ((objectSpacePos.x < imageHalfWidth) &&
2216 						(objectSpacePos.x > -imageHalfWidth) &&
2217 						(objectSpacePos.y < imageHalfHeight) &&
2218 						(objectSpacePos.y > -imageHalfHeight)) {
2219 							return entity;
2220 						}
2221 					}
2222 				}
2223 			}
2224 			return null;
2225 		}
2226 		/**
2227 		 * Check a circle against the hgrid.
2228 		 * @methodOf VENISON.GRAPHICS.GraphicsManager.prototype
2229 		 * @name fnCheckCircleAgainstGrid
2230 		 * @param {Object} iPos The midpoint of the circle.
2231 		 * @param {Number} iRadius The radius of the circle.
2232 		 * @param {Function} iCallbackFunction The function to be called on potential collision, taking the potentially colliding entity as its only argument.
2233 		 * @ignore
2234 		 */
2235 		this.fnCheckCircleAgainstGrid = function(iPos, iRadius, iCallbackFunction) {
2236 			mHGrid.fnCheckCircleAgainstGrid(iPos, iRadius, iCallbackFunction);
2237 		}
2238 		/**
2239 		 * Get all the entities within a rectangle.
2240 		 * @methodOf VENISON.GRAPHICS.GraphicsManager.prototype
2241 		 * @name fnGetEntitiesInRect
2242 		 * @param {Number} iHalfWidth Half the width of the rect.
2243 		 * @param {Number} iHalfHeight Half the height of the rect.
2244 		 * @param {VENISON.UTILITIES.Transformation} iTransformation The transformation of the rect.
2245 		 * @param {Boolean} iOnlyFullyInside If true, only entities that are fully contained within the rect are returned.
2246 		 * @returns {Array} An array of the entities contained fully (if iOnlyFullyInside = true) or partially (iOnlyFullyInside = false).
2247 		 */
2248 		this.fnGetEntitiesInRect = function(iHalfWidth, iHalfHeight, iTransformation, iOnlyFullyInside) {
2249 
2250 			var potentialEntities = [];
2251 			var radius = Math.sqrt(iHalfWidth * iHalfWidth + iHalfHeight * iHalfHeight);
2252 			this.fnCheckCircleAgainstGrid(iTransformation.position, radius, function (iEntity) {
2253 				potentialEntities[iEntity.id] = true;
2254 			});
2255 			var result = [];
2256 			var numLayers = mEntitiesByLayer.length;
2257 			for (var i = 0; i < numLayers; i++) {
2258 				if (mEntitiesByLayer[i]) {
2259 					var layerLength = mEntitiesByLayer[i].length;
2260 					for (var j = 0; j < layerLength; j++) {
2261 						var entity = mEntitiesByLayer[i][j];
2262 						if (!potentialEntities[entity.id]) { //Early out
2263 							continue;
2264 						}
2265 						var entityTransformation = entity.transformation;
2266 						var position = entityTransformation.position;
2267 						var halfWidth = 0.5 * entity.graphicsImage.width;
2268 						var halfHeight = 0.5 * entity.graphicsImage.height;
2269 
2270 						var cornersLocally = [new Vector2(-halfWidth, -halfHeight), new Vector2(-halfWidth, halfHeight), new Vector2(halfWidth, -halfHeight), new Vector2(halfWidth, halfHeight)];
2271 
2272 						var cornersInWorld = [entityTransformation.fnLocalToWorld(cornersLocally[0]), entityTransformation.fnLocalToWorld(cornersLocally[1]), entityTransformation.fnLocalToWorld(cornersLocally[2]), entityTransformation.fnLocalToWorld(cornersLocally[3])];
2273 
2274 						var cornersInOBB = [iTransformation.fnWorldToLocal(cornersInWorld[0]), iTransformation.fnWorldToLocal(cornersInWorld[1]), iTransformation.fnWorldToLocal(cornersInWorld[2]), iTransformation.fnWorldToLocal(cornersInWorld[3])];
2275 
2276 						var k = 0;
2277 						for (; k < 4; k++) { //Check each corner to see if it is inside the given rect
2278 							var corner = cornersInOBB[k];
2279 							var x = corner.x;
2280 							var y = corner.y;
2281 							if (x > -iHalfWidth && x < iHalfWidth && y > -iHalfHeight && y < iHalfHeight) { //If the current corner is contained within the rect
2282 								if (!iOnlyFullyInside) {
2283 									result.push(entity); //It is enough to find one corner within the rect if iOnlyFullInside is false
2284 									break;
2285 								}
2286 							} else if (iOnlyFullyInside) { //If one of the corners isn't inside the rect and we should only include entities fully contained, then no need to check the other corners
2287 								break;
2288 							}
2289 						}
2290 						if (iOnlyFullyInside && k === 4) { //If we got through the whole loop on iOnlyFullyInside = true it means all four corners were contained within the rect
2291 							result.push(entity);
2292 						}
2293 					}
2294 				}
2295 			}
2296 			return result;
2297 		}
2298 	}
2299 })();
2300 (function () {
2301 
2302 	var GraphicsManager = VENISON.GRAPHICS.GraphicsManager;
2303 	var Transformation = VENISON.UTILITIES.Transformation;
2304 	var Vector2 = VENISON.UTILITIES.Vector2;
2305 
2306 	/**
2307 	 * @class A camera, responsible for drawing entities to a canvas.
2308 	 * @param {Object} iCanvas The canvas element that this camera should use for rendering.
2309 	 * @param {Boolean} iUseWebGL2D If set to any non-false value, the experimental WebGL2D will be used for rendering, if the browser supports WebGL.
2310 	 */
2311 	VENISON.GRAPHICS.Camera = function (iCanvas, iUseWebGL2D) {
2312 		var that = this; //private method hack
2313 
2314 		//private
2315 		var mCanvas = iCanvas;
2316 
2317 		var mContext;
2318 
2319 		if (iUseWebGL2D) {
2320 			//Enable WebGL2D here regardless of whether it will be used or not.
2321 			try {
2322 				WebGL2D.enable(mCanvas);
2323 				mContext = mCanvas.getContext('webgl-2d');
2324 			} catch(e) {
2325 				mContext = mCanvas.getContext('2d');
2326 				log("Couldn't initialize WebGL2D! Using regular 2d-context instead!");
2327 			}
2328 		} else {
2329 			mContext = mCanvas.getContext('2d');
2330 		}
2331 
2332 		var mEntities = GraphicsManager.fnGetEntities(); //Get a pointer to the array of all entities to be drawn
2333 
2334 		var mViewportFlags = [];
2335 
2336 		//Debug info stuff
2337 		var mLastTime = 0;
2338 		var mMaxFps = -Infinity;
2339 		var mMinFps = Infinity;
2340 		var mEntitiesDrawn = 0;
2341 		var mEntitiesCulled = 0;
2342 		var textStartX =10, textStartY = 20, textOffsetY = 12, textCounter = 0;
2343 		/**
2344 		 * Render debug information such as framerate etc.
2345 		 * @param {Object} iContext The 2D context to draw on.
2346 		 * @ignore
2347 		 */
2348 		function mfnRenderDebugInfo(iContext) {
2349 			textCounter = 0;
2350 			var d = new Date();
2351 			var now = d.getTime();
2352 			delete d;
2353 			if (!mLastTime) {
2354 				mLastTime = now;
2355 				return;
2356 			}
2357 			var frameTime = now - mLastTime;
2358 			mLastTime = now;
2359 			iContext.font = "bold 12px sans-serif";
2360 			var currentFps = (1000/frameTime);
2361 			if (currentFps < mMinFps) {
2362 				mMinFps = currentFps;
2363 			}
2364 			if (currentFps > mMaxFps) {
2365 				mMaxFps = currentFps;
2366 			}
2367 			iContext.fillText("FPS:", textStartX, textStartY + textOffsetY*textCounter++);
2368 			iContext.fillText("Current: " + currentFps.toFixed(0), textStartX, textStartY + textOffsetY*textCounter++);
2369 			iContext.fillText("Max: " + mMaxFps.toFixed(0),textStartX, textStartY + textOffsetY*textCounter++);
2370 			iContext.fillText("Min: " + mMinFps.toFixed(0), textStartX, textStartY + textOffsetY*textCounter++);
2371 			iContext.fillText("Entities drawn: " + mEntitiesDrawn, textStartX, textStartY + textOffsetY*textCounter++);
2372 			iContext.fillText("Entities culled: " + mEntitiesCulled, textStartX, textStartY + textOffsetY*textCounter++);
2373 		}
2374 
2375 		/**
2376 		 * Check if the entity should be drawn this frame.
2377 		 * @param {VENISON.ENTITY.GameEntity} iEntity The entity to check.
2378 		 * @ignore
2379 		 */
2380 		function mfnShouldBeDrawn(iEntity) {
2381 			if (!iEntity.attributes.graphicsVisible) {
2382 				return false;
2383 			}
2384 
2385 			//Viewport culling
2386 			if (mViewportFlags[iEntity.id]) {
2387 				mEntitiesDrawn ++;
2388 				mViewportFlags[iEntity.id] = false;
2389 				return true;
2390 			}
2391 			mEntitiesCulled ++;
2392 			return false;
2393 		}
2394 
2395 		/**
2396 		 * Prepare the context.
2397 		 * @param {Object} iContext The context to prepare.
2398 		 * @ignore
2399 		 */
2400 		function mfnPrepareContext(iContext) {
2401 			iContext.translate(mCanvas.width*0.5, mCanvas.height*0.5);
2402 			iContext.rotate(-that.transformation.rotation);
2403 			iContext.scale(1/that.transformation.scale.x, 1/that.transformation.scale.y);
2404 			iContext.translate(-that.transformation.position.x, -that.transformation.position.y);
2405 		}
2406 
2407 		//public
2408 		/**
2409 		 * Boolean used to tell the camera to render various debug information.
2410 		 * @type Boolean
2411 		 */
2412 		this.renderDebugInfo = false;
2413 		/**
2414 		 * Boolean used to tell the camera to render entities or not.
2415 		 * @type Boolean
2416 		 */
2417 		this.renderGraphics = true;
2418 		/**
2419 		 * The cameras transformation.
2420 		 * @type VENISON.UTILITIES.Transformation
2421 		 */
2422 		this.transformation = new Transformation(0,0,0,1,1);
2423 		/**
2424 		 * Get the 2D context this camera uses for rendering.
2425 		 * @function
2426 		 * @returns {Object} The 2D context.
2427 		 */
2428 		this.fnGetContext = function () {
2429 			mfnPrepareContext(mContext);
2430 			return mContext;
2431 		}
2432 		/**
2433 		 * Transform a document position into world coordinates.
2434 		 * @function
2435 		 * @param {Object} iDocPos The document position.
2436 		 * @returns {VENISON.UTILITIES.Vector2} The position in world space.
2437 		 */
2438 		this.fnTransformDocumentPositionToWorld = function (iDocPos) {
2439 			result = new VENISON.UTILITIES.Vector2(iDocPos.x - mCanvas.offsetLeft, iDocPos.y - mCanvas.offsetTop);
2440 			result.x -=  mCanvas.width*0.5;
2441 			result.y -=  mCanvas.height*0.5;
2442 			result = this.transformation.fnLocalToWorld(result);
2443 			return result;
2444 		}
2445 		/**
2446 		 * Called every frame to update the graphics.
2447 		 * @function
2448 		 * @ignore
2449 		 */
2450 		this.fnUpdate = function () {
2451 			//reset the canvas
2452 			mContext.setTransform(1,0,0,1,0,0);
2453 			var cs = document.defaultView.getComputedStyle(mCanvas,null);
2454 			var bgcolor = cs.getPropertyValue('background-color');
2455 			if (bgcolor !== "rgba(0, 0, 0, 0)" && bgcolor !== "transparent") {
2456 				mContext.fillStyle = bgcolor;
2457 			}
2458 			mContext.fillRect(0, 0, mCanvas.width, mCanvas.height);
2459 
2460 			if(this.renderGraphics) {
2461 				//Tell the GraphicsManager to flag the entities to draw on this camera
2462 				var radius = new Vector2(0.5 * this.transformation.scale.x * mCanvas.width, 0.5 * this.transformation.scale.y * mCanvas.height).fnLength();
2463 				GraphicsManager.fnCheckCircleAgainstGrid(this.transformation.position,
2464 				radius, function (iEntity) {
2465 					mViewportFlags[iEntity.id] = true;
2466 				});
2467 				mContext.save(); //Save current transformation matrix
2468 
2469 				mfnPrepareContext(mContext);
2470 
2471 				var numEntities = mEntities.length;
2472 				for (var graphicsLayer = 0; graphicsLayer < numEntities; graphicsLayer++) {
2473 					if(mEntities[graphicsLayer]) {
2474 						var layerLength = mEntities[graphicsLayer].length;
2475 						for (var i = 0; i < layerLength; i++) {
2476 							var entity = mEntities[graphicsLayer][i];
2477 							if (mfnShouldBeDrawn(entity)) {
2478 
2479 								var image = entity.graphicsImage;
2480 								var halfWidth = image.width * 0.5;
2481 								var halfHeight = image.height *0.5;
2482 								var entityTransformation = entity.transformation;
2483 								if (entityTransformation.rotation === 0 && entityTransformation.scale.x === 1 && entityTransformation.scale.y === 1) {
2484 									mContext.drawImage(image, entityTransformation.position.x-halfWidth, entityTransformation.position.y-halfHeight); //Center the image over the entity's position
2485 								} else {
2486 									mContext.save(); //Save current transformation matrix
2487 									mContext.translate(entityTransformation.position.x,entityTransformation.position.y);
2488 									if (entityTransformation.rotation) {
2489 										mContext.rotate(entityTransformation.rotation);
2490 									}
2491 									if (entityTransformation.scale.x != 1 || entityTransformation.scale.y != 1) {
2492 										mContext.scale(entityTransformation.scale.x, entityTransformation.scale.y);
2493 									}
2494 									mContext.drawImage(image, -halfWidth, -halfHeight); //Center the image over the entity's position
2495 									mContext.restore(); //Restore the transformation matrix
2496 								}
2497 							}
2498 						}
2499 					}
2500 				}
2501 
2502 				mContext.restore(); //Restore the transformation matrix
2503 			}
2504 
2505 			if (this.renderDebugInfo) {
2506 				mfnRenderDebugInfo(mContext);
2507 				mEntitiesDrawn = 0;
2508 				mEntitiesCulled = 0;
2509 			}
2510 
2511 		}
2512 	}
2513 })();
2514 (function () {
2515 	/**
2516 	 * @class The core game entity,
2517 	 * which really is only a structure to maintain a set of properties and their corresponding attributes.
2518 	 *
2519 	 */
2520 	VENISON.ENTITY.GameEntity = function () {
2521 		//private
2522 		var mName = '';
2523 		var mProperties = [];
2524 		var mPropertyMessageMap = {};
2525 		/**
2526 		 * The transformation of this entity, in world space, describing its position, rotation and scale. <br />
2527 		 * NOTE: Don't set this explicitly! To change an entitys transformation, use the following messages: <br />
2528 		 * 	'setPosition' (content = {x: Number, y: Number}) to set the entity's position.<br />
2529 		 * 	'setRotation' (content = Number) to set the entity's rotation (that is, its angle - not it's angular velocity).<br />
2530 		 * 	'setScale' (content = {x: Number, y: Number}) to set the entity's scale in both axes
2531 		 * @type VENISON.UTILITIES.Transformation
2532 		 */
2533 		this.transformation = null;
2534 
2535 		/**
2536 		 * The HTML image element that is used to display this entity. It is initialized by the GraphicsProperty, but feel free to point it to another image element (possibly created using document.createElement('img')) at will to change the looks of the entity. Just keep in mind that the physics shapes will not be affected at all.
2537 		 * @type Image
2538 		 */
2539 		this.graphicsImage = null;
2540 		/**
2541 		 * The unique ID of this entity, to be set by the {@link VENISON.ENTITY.EntityManager} upon registration.
2542 		 * NOTE: Use to identify the entity, but NEVER ALTER!
2543 		 * @type Number
2544 		 */
2545 		this.id = -1;
2546 
2547 		/**
2548 		 * The attributes that this entity has been given by its attached properties.
2549 		 * @type Object
2550 		 */
2551 		this.attributes = {};
2552 
2553 		/**
2554 		 * Set the name of this entity.
2555 		 * @param {String} iName
2556 		 * @return {Boolean} true if the name was set, false if the name was taken and hence not set.
2557 		 */
2558 		this.fnSetName = function (iName) {
2559 			if (VENISON.ENTITY.EntityManager.fnSetEntityName(this, iName)) {
2560 				mName = iName;
2561 				return true;
2562 			}
2563 			return false;
2564 		}
2565 		/**
2566 		 * Get the unique name of this entity.
2567 		 * @returns {String} The unique name of this entity.
2568 		 */
2569 		this.fnGetName = function () {
2570 			return mName;
2571 		}
2572 		/**
2573 		 * Attaches a property to this entity, and makes the property aware of it by calling its fnAttachToEntity() method.
2574 		 * NOTE: There will be no indiciation if a similar property is already attached to the entity, but if that is the case, strange things may happen. You have been warned.
2575 		 * @param {VENISON.PROPERTY.Property} iProperty The instanciated property to attach to this entity.
2576 		 */
2577 		this.fnAttachProperty = function (iProperty) {
2578 			mProperties.push(iProperty);
2579 			iProperty.fnAttachToEntity(this);
2580 		}
2581 		/**
2582 		 * Called from {@link VENISON.TOOLS.LevelLoader} when the level has been completely loaded.
2583 		 * Simply relays the call to the attached properties.
2584 		 * @ignore
2585 		 */
2586 		this.fnOnLevelLoaded = function () {
2587 			var numProps = mProperties.length;
2588 			for (var i = 0; i < numProps; i ++) {
2589 				mProperties[i].fnOnLevelLoaded();
2590 			}
2591 		}
2592 		/**
2593 		 * Called once every frame from {@link VENISON.ENTITY.EntityManager}.
2594 		 * Simply relays the call to the attached properties.
2595 		 * @ignore
2596 		 */
2597 		this.fnOnFrame = function () {
2598 			var numProps = mProperties.length;
2599 			for (var i = 0; i < numProps; i ++) {
2600 				mProperties[i].fnOnFrame();
2601 			}
2602 		}
2603 		/**
2604 		 * Called when this entity is removed from the game via {@link VENISON.ENTITY.EntityManager}.
2605 		 * Relays the call to the attached properties, and tells the focus manager to reset any focus that this entity currently possesses.
2606 		 * @ignore
2607 		 */
2608 		this.fnOnRemoved = function () {
2609 			var numProps = mProperties.length;
2610 			for (var i = 0; i < numProps; i ++) {
2611 				mProperties[i].fnOnRemoved();
2612 			}
2613 
2614 			//Reset focus if we had focus
2615 			var FocusManager = VENISON.GENERAL.FocusManager;
2616 			if (FocusManager.fnGetCameraFocusEntityID() === this.id) {
2617 				FocusManager.fnSetCameraFocusEntityID(null);
2618 			}
2619 			if (FocusManager.fnGetInputFocusEntityID() === this.id) {
2620 				FocusManager.fnSetInputFocusEntityID(null);
2621 			}
2622 		}
2623 		/**
2624 		 * Called from {@link VENISON.MESSAGES.MessageManager} when a message is sent with a 'to'-field value matching the id of this entity.
2625 		 * Relays the message to all properties having registered themselves as willing to receive messages of the current type.
2626 		 * @ignore
2627 		 */
2628 		this.fnHandleMessage = function (iMessage) {
2629 			var propertiesToHandleMessage = mPropertyMessageMap[iMessage.type];
2630 
2631 			if (!propertiesToHandleMessage) {
2632 				return;
2633 			}
2634 			var numPropertiesToHandleMessage = propertiesToHandleMessage.length;
2635 			for (var i = 0; i < numPropertiesToHandleMessage; i ++) {
2636 				propertiesToHandleMessage[i].fnHandleMessage(iMessage);
2637 			}
2638 		}
2639 		/**
2640 		 * Called from a descendant of {@link VENISON.PROPERTY.Property} in order to register itself to receive messages of a certain type.
2641 		 * @param {VENISON.PROPERTY.Property} iProperty The property to register to receive messages of a certain type.
2642 		 * @param {String} iMessageType The type of messages that the property should receive.
2643 		 */
2644 		this.fnRegisterForMessage = function (iProperty, iMessageType) {
2645 			if (!mPropertyMessageMap[iMessageType]) { //If it is the first time this message type shows up, create a new array for it
2646 				mPropertyMessageMap[iMessageType] = [];
2647 			}
2648 			mPropertyMessageMap[iMessageType].push(iProperty);
2649 		}
2650 		/**
2651 		 * Get all properties currently attached to this entity.
2652 		 * @returns {Array} An array containing references (so be careful) to all properties currently attached to this entity.
2653 		 */
2654 		this.fnGetProperties = function () {
2655 			return mProperties;
2656 		}
2657 		/**
2658 		 * Remove a property from the entity.
2659 		 * @param {String} iPropertyName The name of the property to remove.
2660 		 * @returns {Boolean} true if the property was found and removed, false if no property with the given name was found.
2661 		 */
2662 		this.fnRemoveProperty = function (iPropertyName) {
2663 			var numProperties = mProperties.length;
2664 			for(var i = 0; i < numProperties; i++) {
2665 				if(mProperties[i].fnGetName() === iPropertyName) {
2666 					var propertyToRemove = mProperties[i];
2667 					propertyToRemove.fnOnRemoved();
2668 					mProperties[i] = mProperties[numProperties-1];
2669 					mProperties.pop(); //Truncate last element
2670 					delete propertyToRemove;
2671 					return true;
2672 				}
2673 			}
2674 			return false;
2675 		}
2676 	}
2677 })();
2678 (function () {
2679 	var Message = VENISON.MESSAGES.Message;
2680 	var MessageManager = VENISON.MESSAGES.MessageManager;
2681 
2682 	/**
2683 	 * @class Singleton that handles the foci: input focus and camera focus.
2684 	 */
2685 	VENISON.GENERAL.FocusManager = new function () {
2686 		var mShouldSwitchFocusEntity = [false, false];
2687 		var CAMERAFOCUSINDEX = 0;
2688 		var INPUTFOCUSINDEX = 1;
2689 
2690 		//private
2691 		var mFocusID = [null, null];
2692 
2693 		var mFocusEntityIDNextFrame = [null, null];
2694 
2695 		var mFocusMessage = ['cameraFocus', 'inputFocus'];
2696 
2697 		function mfnSwitchFocusEntity(iFocusIndex) {
2698 			var currentFocusID = mFocusID[iFocusIndex];
2699 			// Check if an entity already has focus
2700 			if(currentFocusID != null) {
2701 				if(currentFocusID === mFocusEntityIDNextFrame[iFocusIndex]) { //Switching to the same id is unnecessary
2702 					return;
2703 				}
2704 				if (null != VENISON.ENTITY.EntityManager.fnGetEntityByID(currentFocusID)) { //Check whether the entity who had focus still exists
2705 					var focusLostMessage = new Message(mFocusMessage[iFocusIndex]+"Lost",currentFocusID, null, null);
2706 					MessageManager.fnSendMessage(focusLostMessage); // Inform the entity that it lost focus
2707 				}
2708 			}
2709 
2710 			//Switch focusentityid
2711 			currentFocusID = mFocusID[iFocusIndex] = mFocusEntityIDNextFrame[iFocusIndex];
2712 
2713 			// Tell the entity that it gained focus
2714 			if (currentFocusID != null) {
2715 				var focusGainedMessage = new Message(mFocusMessage[iFocusIndex]+"Gained",currentFocusID, null, null);
2716 				MessageManager.fnSendMessage(focusGainedMessage);
2717 			}
2718 		}
2719 
2720 		/**
2721 		 * The update function, run once every frame. Switches focus to new focus entity if it has been requested the last frame.
2722 		 * @ignore
2723 		 * @methodOf VENISON.GENERAL.FocusManager.prototype
2724 		 */
2725 		this.fnUpdate = function () {
2726 			if (mShouldSwitchFocusEntity[CAMERAFOCUSINDEX]) {
2727 				mfnSwitchFocusEntity(CAMERAFOCUSINDEX);
2728 				mShouldSwitchFocusEntity[CAMERAFOCUSINDEX] = false;
2729 			}
2730 
2731 			if (mShouldSwitchFocusEntity[INPUTFOCUSINDEX]) {
2732 				mfnSwitchFocusEntity(INPUTFOCUSINDEX);
2733 				mShouldSwitchFocusEntity[INPUTFOCUSINDEX] = false;
2734 			}
2735 		}
2736 		/**
2737 		 * Get the id of the entity who currently has input focus.
2738 		 * @returns {Number} The id of the entity who currently has input focus, or null if no entity has input focus.
2739 		 * @methodOf VENISON.GENERAL.FocusManager.prototype
2740 		 * @name fnGetInputFocusEntityID
2741 		 */
2742 		this.fnGetInputFocusEntityID = function () {
2743 			return mFocusID[INPUTFOCUSINDEX];
2744 		}
2745 		/**
2746 		 * Get the id of the entity who currently has camera focus.
2747 		 * @returns {Number} The id of the entity who currently has camera focus, or null if no entity has camera focus.
2748 		 * @methodOf VENISON.GENERAL.FocusManager.prototype
2749 		 * @name fnGetCameraFocusEntityID
2750 		 */
2751 		this.fnGetCameraFocusEntityID = function () {
2752 			return mFocusID[CAMERAFOCUSINDEX];
2753 		}
2754 		/**
2755 		 * Set the entity who should have input focus. The switch will be made after the current frame.
2756 		 * @param {Number} iEntityID The id of the entity to receive input focus after the current frame.
2757 		 * @methodOf VENISON.GENERAL.FocusManager.prototype
2758 		 * @name fnSetInputFocusEntityID
2759 		 * @see VENISON.GENERAL.FocusManager#fnSetCameraFocusEntityID
2760 		 * @see VENISON.GENERAL.FocusManager#fnSetFocusEntityID
2761 		 */
2762 		this.fnSetInputFocusEntityID = function (iEntityID) {
2763 			mFocusEntityIDNextFrame[INPUTFOCUSINDEX] = iEntityID;
2764 			mShouldSwitchFocusEntity[INPUTFOCUSINDEX] = true;
2765 		}
2766 		/**
2767 		 * Set the entity who should have camera focus. The switch will be made after the current frame.
2768 		 * @param {Number} iEntityID The id of the entity to receive camera focus after the current frame.
2769 		 * @methodOf VENISON.GENERAL.FocusManager.prototype
2770 		 * @name fnSetCameraFocusEntityID
2771 		 * @see VENISON.GENERAL.FocusManager#fnSetInputFocusEntityID
2772 		 * @see VENISON.GENERAL.FocusManager#fnSetFocusEntityID
2773 		 */
2774 		this.fnSetCameraFocusEntityID = function (iEntityID) {
2775 			mFocusEntityIDNextFrame[CAMERAFOCUSINDEX] = iEntityID;
2776 			mShouldSwitchFocusEntity[CAMERAFOCUSINDEX] = true;
2777 		}
2778 		/**
2779 		 * Convenience method to give an entity both camera focus and input focus.
2780 		 * @param {Number} iEntityID The id of the entity to receive camera focus and input focus after the current frame.
2781 		 * @methodOf VENISON.GENERAL.FocusManager.prototype
2782 		 * @name fnSetFocusEntityID
2783 		 * @see VENISON.GENERAL.FocusManager#fnSetInputFocusEntityID
2784 		 * @see VENISON.GENERAL.FocusManager#fnSetCameraFocusEntityID
2785 		 */
2786 		this.fnSetFocusEntityID = function (iEntityID) {
2787 			this.fnSetInputFocusEntityID(iEntityID);
2788 			this.fnSetCameraFocusEntityID(iEntityID);
2789 		}
2790 		/**
2791 		 * Called from {@link VENISON.TOOLS.LevelLoader} when the level is unloaded, to reset the focus settings.
2792 		 * @ignore
2793 		 */
2794 		this.fnOnLevelUnloaded = function () {
2795 			mShouldSwitchFocusEntity = [false, false];
2796 			mFocusID = [null, null];
2797 			mFocusEntityIDNextFrame = [null, null];
2798 		}
2799 	}
2800 })();
2801 (function () {
2802 	var Vector2 = VENISON.UTILITIES.Vector2;
2803 	/**
2804 	 * @class The InputManager handles keyboard input.
2805 	 * Handling of mouse input is very game specific and it is much more efficient to just add mouse listeners on the specific elements that should be clickable.
2806 	 */
2807 	VENISON.GENERAL.InputManager = new function () {
2808 		var mKeysPressed = []; //A key is pressed only a single frame
2809 		var mKeysReleased = []; //A key is released only a single frame
2810 		var mKeysDown = []; //A key that remains pressed down stays in mKeysDown for as long as it is held down
2811 
2812 		document.addEventListener('keydown', function (e) {
2813 			if (e === undefined) {
2814 				e = window.event;
2815 			}
2816 
2817 			if (!mKeysDown[e.keyCode]) {
2818 				mKeysPressed[e.keyCode] = true;
2819 			}
2820 
2821 			mKeysDown[e.keyCode] = true;
2822 
2823 		}, false);
2824 		document.addEventListener('keyup', function (e) {
2825 			if (e === undefined) {
2826 				e = window.event;
2827 			}
2828 
2829 			mKeysReleased[e.keyCode] = true;
2830 			//delete mKeysPressed[e.keyCode+''];
2831 			mKeysDown[e.keyCode] = false;
2832 
2833 		}, false);
2834 		/**
2835 		 * Used internally to clear the pressed and released events every frame.
2836 		 * @ignore
2837 		 */
2838 		this.fnUpdate = function () {
2839 			mKeysPressed = {};
2840 			mKeysReleased = {};
2841 		}
2842 		/**
2843 		 * Call to check whether a key with a certain key code was pressed this frame.
2844 		 * @param {Number} iKeyCode The key code of the query.
2845 		 * @returns {Boolean} true if the key was pressed this frame, otherwise false.
2846 		 * @methodOf VENISON.GENERAL.InputManager.prototype
2847 		 * @name fnIsKeyPressed
2848 		 */
2849 		this.fnIsKeyPressed = function (iKeyCode) {
2850 			return mKeysPressed[iKeyCode] === true; //We cannot only return the value for the keycode in the keyboard state, since it could be undefined
2851 		}
2852 		/**
2853 		 * Call to check whether a key with a certain key code was released this frame.
2854 		 * @param {Number} iKeyCode The key code of the query.
2855 		 * @returns {Boolean} true if the key was released this frame, otherwise false.
2856 		 * @methodOf VENISON.GENERAL.InputManager.prototype
2857 		 * @name fnIsKeyReleased
2858 		 */
2859 		this.fnIsKeyReleased = function (iKeyCode) {
2860 			return mKeysReleased[iKeyCode] === true;
2861 		}
2862 		/**
2863 		 * Call to check whether a key with a certain key code is being pressed down.
2864 		 * @param {Number} iKeyCode The key code of the query.
2865 		 * @returns {Boolean} true if the key is being pressed down, otherwise false.
2866 		 * @methodOf VENISON.GENERAL.InputManager.prototype
2867 		 * @name fnIsKeyDown
2868 		 */
2869 		this.fnIsKeyDown = function (iKeyCode) {
2870 			return mKeysDown[iKeyCode] === true;
2871 		}
2872 	}
2873 })();
2874 (function() {
2875 	/**
2876 	 * @class A factory singleton to handle properties.
2877 	 */
2878 	VENISON.PROPERTY.PropertyFactory = new function() {
2879 		// Dictionary containing the property names as keys and constructor functions as values
2880 		var mProperties = {};
2881 		/**
2882 		 * Create a certain property, optionally with certain attributes.
2883 		 * @param {String} iPropertyName The name of the property to create, as previously registered with {@link VENISON.PROPERTY.PropertyFactory#fnRegisterProperty}.
2884 		 * @param {Object} iPropertyAttributes [optional] The attributes object to assign to the newly created property, that can be really anything. If left empty, the property will have its self-declared default attributes.
2885 		 * @returns {Object} The created property.
2886 		 * @methodOf VENISON.PROPERTY.PropertyFactory.prototype
2887 		 * @name fnCreateProperty
2888 		 */
2889 		this.fnCreateProperty = function(iPropertyName, iPropertyAttributes) {
2890 			if (!mProperties[iPropertyName]) {
2891 				throw "Error in VENISON.PROPERTY.PropertyFactory: No property named '" + iPropertyName + "'!";
2892 			}
2893 
2894 			var newProperty = new mProperties[iPropertyName]();
2895 
2896 			for (var attr in iPropertyAttributes) {
2897 				newProperty.attributes[attr] = iPropertyAttributes[attr];
2898 			}
2899 
2900 			return newProperty;
2901 		}
2902 		/**
2903 		 * Register a property constructor with the Property Factory, in order to be able to create it via {@link VENISON.PROPERTY.PropertyFactory#fnCreateProperty}.<br />
2904 		 * See <a href='/jsdoc/symbols/src/property_template.js.html'>the property template</a> for details on use.
2905 		 * @param {String} iPropertyname The name under which to register the property.
2906 		 * @param {VENISON.PROPERTY.Property} iProperty The constructor for the property being registered.
2907 		 * @methodOf VENISON.PROPERTY.PropertyFactory.prototype
2908 		 * @name fnRegisterProperty
2909 		 *
2910 		 *
2911 		 */
2912 		this.fnRegisterProperty = function(iPropertyName, iProperty) {
2913 			if (mProperties[iPropertyName]) {
2914 				throw "Error in VENISON.PROPERTY.PropertyFactory: A property named '" + iPropertyName + "' has already been registered!";
2915 			}
2916 			iProperty.prototype = new VENISON.PROPERTY.Property();
2917 			iProperty.prototype.fnGetName = function() {
2918 				return iPropertyName;
2919 			}
2920 			mProperties[iPropertyName] = iProperty;
2921 		}
2922 		/**
2923 		 * Get an array with the names of all properties currently registered in the property factory.
2924 		 * @returns An array with the names of all properties currently registered in the property factory.
2925 		 * @methodOf VENISON.PROPERTY.PropertyFactory.prototype
2926 		 * @name fnGetPropertyNames
2927 		 */
2928 		this.fnGetPropertyNames = function() {
2929 			var result = [];
2930 			for (var propertyName in mProperties) {
2931 				result.push(propertyName);
2932 			}
2933 			return result;
2934 		}
2935 	}
2936 })();
2937 (function () {
2938 	/**
2939 	 *  @class The ABSTRACT base class for all properties. NOTE: Never instanciate this one!
2940 	 */
2941 	VENISON.PROPERTY.Property = function () {
2942 		/**
2943 		 * The entity that this property is attached to. DO NOT override in subclass, and DO NOT alter explicitly.
2944 		 * @type VENISON.ENTITY.GameEntity
2945 		 */
2946 		this.entity = null;
2947 
2948 		/**
2949 		 * The attributes object to extend the attributes object of the entity on attachment. Override in subclasses as needed.
2950 		 * @type Object
2951 		 */
2952 		this.attributes = null;
2953 
2954 		/**
2955 		 * Do not override in subclass.
2956 		 * Makes this property aware of the GameEntity it is attached to.
2957 		 * NOTE: Should only be called from inside fnAttachProperty() in GameEntity.
2958 		 * @ignore
2959 		 */
2960 		this.fnAttachToEntity = function (iEntity) {
2961 			this.entity = iEntity;
2962 
2963 			//Add this.attributes to this.entity's attributes.
2964 			for (var attr in this.attributes) {
2965 				this.entity.attributes[attr] = this.attributes[attr];
2966 			}
2967 
2968 			//Register which messages this property wishes to recieve from the entity
2969 			this.fnRegisterToMessages();
2970 
2971 			this.fnOnAttached();
2972 		}
2973 		/**
2974 		 * Override in subclass (NOTE: this is implicitly done in VENISON.PROPERTY.PropertyFactory.fnRegisterProperty(), so don't do it explicitly!)
2975 		 * @returns {String} The name of this property
2976 		 */
2977 		this.fnGetName = function () {
2978 			throw "A property has to override the function fnGetName()!";
2979 		}
2980 		/**
2981 		 * Override in subclass.
2982 		 * Called when this property has been attached to an entity. mEntity contains a pointer to the entity.
2983 		 */
2984 		this.fnOnAttached = function () {
2985 
2986 		}
2987 		/**
2988 		 * Override in subclass.
2989 		 * Called when the level has been completely loaded.
2990 		 */
2991 		this.fnOnLevelLoaded = function () {
2992 
2993 		}
2994 		/**
2995 		 * Override in subclass.
2996 		 * Called when this property is removed from the entity it was attached to.
2997 		 */
2998 		this.fnOnRemoved = function() {
2999 
3000 		}
3001 		/**
3002 		 * Override in subclass.
3003 		 * Called once every frame.
3004 		 */
3005 		this.fnOnFrame = function () {
3006 
3007 		}
3008 		/**
3009 		 * Override in subclass.
3010 		 * This method is automatically called when this property is attached to an entity. Use it to register which messages this property should be notified of.
3011 		 */
3012 		this.fnRegisterToMessages = function () {
3013 
3014 		}
3015 		/**
3016 		 * Override in subclass.
3017 		 * Called when the game entity that this property is attached to receives a message of a type that this property has registered itself to.
3018 		 * @param {Object} iMessage the message received.
3019 		 */
3020 		this.fnHandleMessage = function (iMessage) {
3021 
3022 		}
3023 	}
3024 })();
3025 (function () {
3026 	var EntityManager = VENISON.ENTITY.EntityManager;
3027 	var GameStateManager = VENISON.GAMESTATES.GameStateManager;
3028 	var PropertyFactory = VENISON.PROPERTY.PropertyFactory;
3029 	var Property = VENISON.PROPERTY.Property;
3030 	var GraphicsManager = VENISON.GRAPHICS.GraphicsManager;
3031 	var PhysicsManager = VENISON.PHYSICS.PhysicsManager;
3032 	var FocusManager = VENISON.GENERAL.FocusManager;
3033 	var InputManager = VENISON.GENERAL.InputManager;
3034 	var MessageManager = VENISON.MESSAGES.MessageManager;
3035 	var Message = VENISON.MESSAGES.Message;
3036 	var AnimationManager = VENISON.GRAPHICS.AnimationManager;
3037 
3038 	/**
3039 	 * @class The fundamental property that every entity has.
3040 	 * It is responsible for keeping the entity up to date in the viewport culling data structure. <br />
3041 	 * <br />
3042 	 * It handles the following messages: <br />
3043 	 * <br />
3044 	 * 'setGraphicsLayer': Received by GraphicsProperty. Used to set the graphics layer. <br />
3045 	 * content = layer <br />
3046 	 * <br />
3047 	 * 'setPosition': Received by GraphicsProperty and PhysicsProperty. Used to set the position of the entity.<br />
3048 	 * content = {x: , y: } The new position <br />
3049 	 * <br />
3050 	 * 'setRotation': Received by GraphicsProperty and PhysicsProperty. Used to set the rotation of the entity. <br />
3051 	 * content = rotation in radians <br />
3052 	 * <br />
3053 	 * 'setScale': Received by GraphicsProperty and PhysicsProperty. Used to scale the entity. <br />
3054 	 * content = {x: , y: } The horizontal and vertical scale <br />
3055 	 *
3056 	 * @name VENISON.PROPERTIES.GraphicsProperty
3057 	 * @augments VENISON.PROPERTY.Property
3058 	 */
3059 	PropertyFactory.fnRegisterProperty('GraphicsProperty', function () {
3060 		var mImage;
3061 		var mHGridObject = null;
3062 		var mPositionOnLastHGridObjectUpdate = {
3063 			x: 0,
3064 			y: 0
3065 		};
3066 		//The attributes object to extend the attributes object of the entity on attachment.
3067 		this.attributes = {
3068 			graphicsTexture: 'image.png',
3069 			graphicsVisible: true,
3070 			graphicsLayer: 0
3071 		};
3072 
3073 		var mImageLoaded = false;
3074 
3075 		//Called when this property has been attached to an entity. mEntity contains a pointer to the entity.
3076 		this.fnOnAttached = function () {
3077 			mImage = document.createElement('img');
3078 			mImage.src = this.entity.attributes.graphicsTexture;
3079 			var that = this;
3080 			that.entity.graphicsImage = mImage;
3081 			mImage.onload = function () {
3082 				mHGridObject = new VENISON.GRAPHICS.HGridObject();
3083 				mHGridObject.entity = that.entity;
3084 				mHGridObject.radius = Math.max(0.5 * mImage.width * that.entity.transformation.scale.x, 0.5 * mImage.height * that.entity.transformation.scale.y);
3085 				GraphicsManager.fnRegisterHGridObject(mHGridObject);
3086 			};
3087 		}
3088 		this.fnOnFrame = function () {
3089 			var pos = this.entity.transformation.position;
3090 			if (mHGridObject && ((mPositionOnLastHGridObjectUpdate.x !== pos.x) || (mPositionOnLastHGridObjectUpdate.y !== pos.y))) { //Check if we have moved since last hgridobject update
3091 				GraphicsManager.fnUpdateHGridObject(mHGridObject);
3092 				mPositionOnLastHGridObjectUpdate.x = pos.x;
3093 				mPositionOnLastHGridObjectUpdate.y = pos.y;
3094 			}
3095 		}
3096 		//Called when this property is removed from the entity it was attached to
3097 		this.fnOnRemoved = function() {
3098 			if (mHGridObject) {
3099 				GraphicsManager.fnRemoveHGridObject(mHGridObject);
3100 				delete mHGridObject;
3101 			} else {
3102 				/*If we have no mHGridObject at this point, it means that
3103 				 this property was removed before its graphicsImage had
3104 				 finished loading (see this.fnOnAttached above). In such a
3105 				 case, the callback of the load event should be cancelled,
3106 				 since it would make no sense to carry it through with a
3107 				 removed property. */
3108 				mImage.onload = null;
3109 			}
3110 		}
3111 		//This method is automatically called when this property is attached to an entity. Use it to register which messages this property should be notified of.
3112 		this.fnRegisterToMessages = function () {
3113 			this.entity.fnRegisterForMessage(this,'setScale');
3114 			this.entity.fnRegisterForMessage(this,'setRotation');
3115 			this.entity.fnRegisterForMessage(this,'setGraphicsLayer');
3116 			this.entity.fnRegisterForMessage(this,'setPosition');
3117 		}
3118 		this.fnHandleMessage = function (iMessage) {
3119 			switch (iMessage.type) {
3120 				case 'setRotation':
3121 					this.entity.transformation.rotation = iMessage.content;
3122 					break;
3123 				case 'setScale':
3124 					var newScaleX = iMessage.content.x;
3125 					var newScaleY = iMessage.content.y;
3126 					if (newScaleX != null) { //Returns false if undefined as well
3127 						this.entity.transformation.scale.x = newScaleX;
3128 					} else {
3129 						newScaleX = 0;
3130 					}
3131 
3132 					if (newScaleY != null) { //Returns false if undefined as well
3133 						this.entity.transformation.scale.y = newScaleY;
3134 					} else {
3135 						newScaleY = 0;
3136 					}
3137 
3138 					mHGridObject.radius = Math.max(0.5 * mImage.width * newScaleX, 0.5 * mImage.height * newScaleY);
3139 					break;
3140 				case 'setGraphicsLayer':
3141 					var newLayer = iMessage.content;
3142 					GraphicsManager.fnSetLayerOfHGridObject(mHGridObject, newLayer);
3143 					break;
3144 				case 'setPosition':
3145 					if(iMessage.content.x != null) {
3146 						this.entity.transformation.position.x = iMessage.content.x;
3147 					}
3148 					if(iMessage.content.y != null) {
3149 						this.entity.transformation.position.y = iMessage.content.y;
3150 					}
3151 					if (mHGridObject) {
3152 						GraphicsManager.fnUpdateHGridObject(mHGridObject);
3153 					}
3154 					break;
3155 			}
3156 		}
3157 	});
3158 	/**
3159 	 * @class A property to enable physics simulation of an entity. <br />
3160 	 * Used to create and modify the physics settings of an entity. <br /><br />
3161 	 *
3162 	 * It handles the following messages:<br />
3163 	 * <br />
3164 	 * 'setPosition': Received by GraphicsProperty and PhysicsProperty. Used to set the position of the entity.<br />
3165 	 * content = {x: , y: } The new position<br />
3166 	 * <br />
3167 	 * 'setRotation': Received by GraphicsProperty and PhysicsProperty. Used to set the rotation of the entity.<br />
3168 	 * content = rotation in radians <br />
3169 	 * <br />
3170 	 * 'setScale': Received by GraphicsProperty and PhysicsProperty. Used to scale the entity.<br />
3171 	 * content = {x: , y: } The horizontal and vertical scale <br />
3172 	 * <br />
3173 	 * 'applyImpulseAt': Received by PhysicsProperty. Apply an impulse to the entity at a specific point. <br />
3174 	 * content.position = {x: , y: } The point in world space on which to apply the impulse <br />
3175 	 * content.impulse = {x: , y: } The impulse in world space <br />
3176 	 * <br />
3177 	 * 'setPhysicsType': Received by PhysicsProperty. Set the physicsType of the physics entity <br />
3178 	 * content = 'dynamic', 'static' or 'kinematic' <br />
3179 	 * <br />
3180 	 * 'addPhysicsShapes': Received by PhysicsProperty. Used to add new physics shapes to the entity. <br />
3181 	 * content = Array of shapes <br />
3182 	 * <br />
3183 	 * 'setLinearVelocity': Received by PhysicsProperty. Used to set the linear velocity of the entity. <br />
3184 	 * content = {x: , y: } The linear velocity in pixels per second<br />
3185 	 * <br />
3186 	 * 'setAngularVelocity': Received by PhysicsProperty. Used to set the angular velocity of the entity. <br />
3187 	 * content =  The angular velocity in radians per second<br />
3188 	 * <br />
3189 	 * 'setCollidesWithForAllShapes': Received by PhysicsProperty. Set the collidesWith attribute for all physics shapes. <br />
3190 	 * content = Array of collision categories <br />
3191 	 * <br />
3192 	 * 'setFixedRotation': Received by PhysicsProperty. Used to lock or unlock the rotation of the entity. <br />
3193 	 * content = true/false <br />
3194 	 * <br />
3195 	 * 'setActive': Received by PhysicsProperty. Used to set wheter the physics entity should take part in the physics simulations or not. <br />
3196 	 * content = true/false <br />
3197 	 *
3198 	 * @name VENISON.PROPERTIES.PhysicsProperty
3199 	 *
3200 	 * @augments VENISON.PROPERTY.Property
3201 	 */
3202 	PropertyFactory.fnRegisterProperty('PhysicsProperty', function () {
3203 		var mScaleX;
3204 		var mScaleY;
3205 
3206 		//The attributes connected to this property that will be added to the entity which it is attached to.
3207 		//If this property does not need any extra attributes, remove this statement.
3208 		//There can be any number of attribute name/value pairs - extend as needed.
3209 		this.attributes = {
3210 			physicsType: 'dynamic',
3211 			physicsFixedRotation: false,
3212 			physicsAngularDamping: 0,
3213 			physicsLinearDamping: 0,
3214 			physicsAllowSleep: true,
3215 			physicsIsBullet: false,
3216 			physicsIsActive: true,
3217 			physicsShapes: {
3218 				shape01: {
3219 					shapeType: 'box',
3220 					collisionCategory: 'default',
3221 					isSensor: false,
3222 					collidesWith: {
3223 						category01: 'default'
3224 					},
3225 					width: 15,
3226 					height: 15,
3227 					localPosition: {
3228 						x: 0,
3229 						y: 0
3230 					},
3231 					localRotation: 0,
3232 					restitution: 0.2,
3233 					friction: 0.5,
3234 					density: 1
3235 				}
3236 			}
3237 		};
3238 
3239 		//@Override
3240 		//Called when this property has been attached to an entity. mEntity contains a pointer to the entity.
3241 		this.fnOnAttached = function () {
3242 			mScaleX = this.entity.transformation.scale.x;
3243 			mScaleY = this.entity.transformation.scale.y;
3244 
3245 			PhysicsManager.fnCreatePhysicsEntity(this.attributes, this.entity);
3246 		}
3247 		//@Override
3248 		//Called just prior to this property being removed from the entity it is attached to
3249 		this.fnOnRemoved = function () {
3250 			PhysicsManager.fnRemovePhysicsEntity(this.entity.id);
3251 		}
3252 		var that = this;
3253 		function mfnAddPhysicsShapes(iShapes) {
3254 			PhysicsManager.fnRemovePhysicsEntity(that.entity.id);
3255 			var numShapes = 0;
3256 			for(var shapes in that.attributes.physicsShapes) {
3257 				numShapes++;
3258 			}
3259 			var shapesLength = iShapes.length;
3260 			for(var i = 0; i < shapesLength; i++) {
3261 				var newShapeName = 'shape' + Math.floor((numShapes + 1)/10) + '' + (numShapes + 1) % 10;
3262 				that.attributes.physicsShapes[newShapeName] = iShapes[i];
3263 				numShapes++;
3264 			}
3265 			PhysicsManager.fnCreatePhysicsEntity(that.attributes, that.entity);
3266 		}
3267 
3268 		function mfnSetScale(iX, iY) {
3269 			var velocityLinear = PhysicsManager.fnGetPhysicsEntityLinearVelocity(that.entity.id);
3270 			var velocityAngular = PhysicsManager.fnGetPhysicsEntityAngularVelocity(that.entity.id);
3271 			PhysicsManager.fnRemovePhysicsEntity(that.entity.id);
3272 			var shapes = that.attributes.physicsShapes;
3273 			for(var s in shapes) {
3274 				var shape = shapes[s];
3275 				if (shape.localPosition) {
3276 					shape.localPosition.x /= mScaleX;
3277 					shape.localPosition.y /= mScaleY;
3278 					shape.localPosition.x *= iX;
3279 					shape.localPosition.y *= iY;
3280 				}
3281 				switch(shape.shapeType) {
3282 					case 'circle':
3283 						shape.radius /= Math.max(mScaleX, mScaleY);
3284 						shape.radius *= Math.max(iX, iY);
3285 						break;
3286 					case 'box':
3287 						shape.width /= mScaleX;
3288 						shape.height /= mScaleY;
3289 						shape.width *= iX;
3290 						shape.height *= iY;
3291 						break;
3292 					case 'polygon':
3293 						var vertices = shape.vertices;
3294 						var invX = 1/mScaleX;
3295 						var invY = 1/mScaleY;
3296 						var vertArray = [];
3297 						for (var i in vertices) {
3298 							var vert = vertices[i];
3299 							vert.x *= invX;
3300 							vert.y *= invY;
3301 							vert.x *= iX;
3302 							vert.y *= iY;
3303 							vertArray.push(vert);
3304 						}
3305 						if ((iX < 0 && iY > 0) || (iX > 0 && iY < 0) ) { //If one and only one of the scales is negative
3306 							var numVerts = vertArray.length;
3307 							var halfNumVerts = Math.floor(numVerts * 0.5);
3308 							for (var i = 0; i < halfNumVerts; i ++) {
3309 								var vert1 = vertArray[i];
3310 								var vert2 = vertArray[numVerts - 1 -i];
3311 								var vert1Copy = {
3312 									x: vert1.x,
3313 									y: vert1.y
3314 								};
3315 								vert1.x = vert2.x;
3316 								vert1.y = vert2.y;
3317 								vert2.x = vert1Copy.x;
3318 								vert2.y = vert1Copy.y;
3319 							}
3320 						}
3321 						break;
3322 				}
3323 
3324 			}
3325 			mScaleX = iX;
3326 			mScaleY = iY;
3327 			PhysicsManager.fnCreatePhysicsEntity(that.attributes, that.entity);
3328 			PhysicsManager.fnSetPhysicsEntityLinearVelocity(that.entity.id, velocityLinear.x, velocityLinear.y);
3329 			PhysicsManager.fnSetPhysicsEntityAngularVelocity(that.entity.id, velocityAngular);
3330 		}
3331 
3332 		function mfnSetCollidesWithForAllShapes(iCollisionCategoryArray) {
3333 			PhysicsManager.fnRemovePhysicsEntity(that.entity.id);
3334 			var shapes = that.attributes.physicsShapes;
3335 			for(var s in shapes) {
3336 				var shape = shapes[s];
3337 				shape.collidesWith = {};
3338 				var collisionCategoryArrayLength = iCollisionCategoryArray.length;
3339 				for (var i = 0; i < collisionCategoryArrayLength; i ++) {
3340 					shape.collidesWith['category' + Math.floor(i/10) + Math.floor(1%10)] = iCollisionCategoryArray[i];
3341 				}
3342 			}
3343 			PhysicsManager.fnCreatePhysicsEntity(that.attributes, that.entity);
3344 		}
3345 
3346 		//@Override
3347 		//This method is automatically called when this property is attached to an entity. Use it to register which messages this property should be notified of.
3348 		this.fnRegisterToMessages = function () {
3349 			this.entity.fnRegisterForMessage(this, 'setPosition');
3350 			this.entity.fnRegisterForMessage(this, 'setRotation');
3351 			this.entity.fnRegisterForMessage(this, 'setScale');
3352 			this.entity.fnRegisterForMessage(this, 'applyImpulseAt');
3353 			this.entity.fnRegisterForMessage(this, 'setPhysicsType');
3354 			this.entity.fnRegisterForMessage(this, 'addPhysicsShapes');
3355 			this.entity.fnRegisterForMessage(this, 'setLinearVelocity');
3356 			this.entity.fnRegisterForMessage(this, 'setAngularVelocity');
3357 			this.entity.fnRegisterForMessage(this, 'setCollidesWithForAllShapes');
3358 			this.entity.fnRegisterForMessage(this, 'setFixedRotation');
3359 			this.entity.fnRegisterForMessage(this, 'setActive');
3360 		}
3361 		//@Override
3362 		//Called when the game entity that this property is attached to receives a message of a type that this property has registered to
3363 		this.fnHandleMessage = function (iMessage) {
3364 			switch (iMessage.type) {
3365 				case 'setRotation':
3366 					PhysicsManager.fnSetPhysicsEntityRotation(this.entity.id, iMessage.content);
3367 					break;
3368 				case 'setScale':
3369 					var newScaleX = this.entity.transformation.scale.x;
3370 					var newScaleY = this.entity.transformation.scale.y;
3371 					if(iMessage.content.x != null) {
3372 						newScaleX = iMessage.content.x;
3373 					}
3374 					if(iMessage.content.y != null) {
3375 						newScaleY = iMessage.content.y;
3376 					}
3377 					mfnSetScale(newScaleX, newScaleY);
3378 					break;
3379 				case 'setPosition':
3380 					var newPosX = this.entity.transformation.position.x;
3381 					var newPosY = this.entity.transformation.position.y;
3382 					if(iMessage.content.x != null) {
3383 						newPosX = iMessage.content.x;
3384 					}
3385 					if(iMessage.content.y != null) {
3386 						newPosY = iMessage.content.y;
3387 					}
3388 					PhysicsManager.fnSetPhysicsEntityPosition(this.entity.id, newPosX, newPosY);
3389 					break;
3390 				case 'applyImpulseAt':
3391 					PhysicsManager.fnApplyImpulseAt(this.entity.id, iMessage.content.position, iMessage.content.impulse);
3392 					break;
3393 				case 'setPhysicsType':
3394 					PhysicsManager.fnSetPhysicsType(this.entity.id, iMessage.content);
3395 					break;
3396 				case 'addPhysicsShapes':
3397 					mfnAddPhysicsShapes(iMessage.content);
3398 					break;
3399 				case 'setLinearVelocity':
3400 					PhysicsManager.fnSetPhysicsEntityLinearVelocity(this.entity.id, iMessage.content.x, iMessage.content.y);
3401 					break;
3402 				case 'setAngularVelocity':
3403 					PhysicsManager.fnSetPhysicsEntityAngularVelocity(this.entity.id, iMessage.content);
3404 					break;
3405 				case 'setCollidesWithForAllShapes':
3406 					mfnSetCollidesWithForAllShapes(iMessage.content);
3407 					break;
3408 				case 'setFixedRotation':
3409 					PhysicsManager.fnSetPhysicsEntityFixedRotation(this.entity.id, iMessage.content);
3410 					break;
3411 				case 'setActive':
3412 					PhysicsManager.fnSetPhysicsEntityActive(this.entity.id, iMessage.content);
3413 					break;
3414 			}
3415 		}
3416 	});
3417 	/**
3418 	 * @class A versatile trigger property that sends message with customizable content to the collidee on contact. May be used with sensors and non-sensors alike.
3419 	 * Handles messages 'physicsOnContactBegin' and 'physicsOnContactEnd' sent internally from {@link VENISON.PHYSICS.PhysicsManager}.
3420 	 * Sends two messages to any other entity that comes into contact with it: onTriggerBegin and onTriggerEnd, sent on contact begin and on contact end, respectively.
3421 	 * The content has two keys, namely 'data' and 'triggerEntity'. The first will be either the onTriggerBeginData or the onTriggerEndData attribute strings as set in the level (most often via the editor).
3422 	 * The latter will always be a pointer to the entity to which this property is attached.
3423 	 * @name VENISON.PROPERTIES.TriggerProperty
3424 	 * @augments VENISON.PROPERTY.Property
3425 	 */
3426 	PropertyFactory.fnRegisterProperty('TriggerProperty', function () {
3427 		this.attributes = {
3428 			onTriggerBeginData: "",
3429 			onTriggerEndData: "",
3430 			removeOnTouch: false
3431 		};
3432 
3433 		this.fnRegisterToMessages = function () {
3434 			this.entity.fnRegisterForMessage(this,'physicsOnContactBegin');
3435 			this.entity.fnRegisterForMessage(this,'physicsOnContactEnd');
3436 		}
3437 		this.fnHandleMessage = function (iMessage) {
3438 			switch (iMessage.type) {
3439 				case 'physicsOnContactBegin':
3440 					var other = iMessage.content.collideeID;
3441 					var content = {
3442 						data: this.entity.attributes.onTriggerBeginData,
3443 						triggerEntity: this.entity
3444 					};
3445 					MessageManager.fnSendMessage(new Message("onTriggerBegin", other, this.entity.id, content));
3446 					if(this.entity.attributes.removeOnTouch) {
3447 						EntityManager.fnRemoveEntity(this.entity);
3448 						this.fnHandleMessage = function () { //Make sure we don't trigger more than once
3449 						};
3450 					}
3451 					break;
3452 				case 'physicsOnContactEnd':
3453 					var other = iMessage.content.collideeID;
3454 					var content = {
3455 						data: this.entity.attributes.onTriggerEndData,
3456 						triggerEntity: this.entity
3457 					};
3458 					MessageManager.fnSendMessage(new Message("onTriggerEnd", other, this.entity.id, content));
3459 					break;
3460 			}
3461 		}
3462 	});
3463 	/**
3464 	 * @class A simple animation property to assign a single, looping animation to an entity.
3465 	 * Handles the message 'pauseAnimation', which is used to pause and resume the animation by setting the message's content to true or false, respectively.
3466 	 * @name VENISON.PROPERTIES.SimpleAnimationProperty
3467 	 * @augments VENISON.PROPERTY.Property
3468 	 */
3469 	PropertyFactory.fnRegisterProperty('SimpleAnimationProperty', function () {
3470 		//@pre graphicsNumberOfFrames has to be > 0
3471 		//@pre graphicsFrameRate has to be >= 0
3472 		this.attributes = {
3473 			graphicsAnimation: '',
3474 			graphicsNumberOfFrames: 2,
3475 			graphicsFrameRate: 12
3476 		};
3477 
3478 		this.fnOnAttached = function () {
3479 			AnimationManager.fnPlayAnimation(this.entity.attributes.graphicsAnimation, this.entity, this.entity.attributes.graphicsFrameRate, 0, true);
3480 		}
3481 		//This method is automatically called when this property is attached to an entity. Use it to register which messages this property should be notified of.
3482 		this.fnRegisterToMessages = function () {
3483 			this.entity.fnRegisterForMessage(this,'pauseAnimation');
3484 		}
3485 		this.fnHandleMessage = function (iMessage) {
3486 			switch (iMessage.type) {
3487 				case 'pauseAnimation':
3488 					AnimationManager.fnSetAnimationPaused(this.entity.id, iMessage.content);
3489 					break;
3490 			}
3491 		}
3492 	});
3493 	/**
3494 	 * @class A property to make a named camera tightly follow an entity with camera focus.
3495 	 * @name VENISON.PROPERTIES.ChaseCameraProperty
3496 	 * @augments VENISON.PROPERTY.Property
3497 	 */
3498 	PropertyFactory.fnRegisterProperty('ChaseCameraProperty', function () {
3499 		this.attributes = {
3500 			cameraName: 'default'
3501 		};
3502 		//Overriden from Property
3503 		//Called once every frame
3504 		this.fnOnFrame = function () {
3505 			//If we have camera focus
3506 			if (this.entity.id === FocusManager.fnGetCameraFocusEntityID()) {
3507 				var camPos = GraphicsManager.fnGetCameraByName(this.entity.attributes.cameraName).transformation.position;
3508 				camPos.x = this.entity.transformation.position.x; //Make the default camera be were our entity is
3509 				camPos.y = this.entity.transformation.position.y;
3510 			}
3511 		}
3512 	});
3513 })();
3514 (function () {
3515 	/**
3516 	 * @class The manager to handle real-time networking.
3517 	 *
3518 	 */
3519 	VENISON.NETWORK.NetworkManager = new function () {
3520 		var mListeners = [];
3521 
3522 		var mSocket = null;
3523 
3524 		function mfnMessageReceived(iMessage) {
3525 			var numListeners = mListeners.length;
3526 			for (var i = 0; i < numListeners; i ++) {
3527 				mListeners[i].fnMessageReceived(iMessage);
3528 			}
3529 		}
3530 
3531 		function mfnMessageSent(iMessage) {
3532 			var numListeners = mListeners.length;
3533 			for (var i = 0; i < numListeners; i ++) {
3534 				mListeners[i].fnMessageSent(iMessage);
3535 			}
3536 		}
3537 
3538 		function mfnConnectionOpened() {
3539 			var numListeners = mListeners.length;
3540 			for (var i = 0; i < numListeners; i ++) {
3541 				mListeners[i].fnConnectionOpened();
3542 			}
3543 		}
3544 
3545 		function mfnConnectionClosed() {
3546 			var numListeners = mListeners.length;
3547 			for (var i = 0; i < numListeners; i ++) {
3548 				mListeners[i].fnConnectionClosed();
3549 			}
3550 		}
3551 
3552 		function mfnExceptionCaught(iException) {
3553 			var numListeners = mListeners.length;
3554 			for (var i = 0; i < numListeners; i ++) {
3555 				mListeners[i].fnExceptionCaught(iException);
3556 			}
3557 		}
3558 
3559 		/**
3560 		 * Register a listener to be notified of network events.
3561 		 * @methodOf VENISON.NETWORK.NetworkManager.prototype
3562 		 * @name fnAddNetworkListener
3563 		 * @param {Object} iListener An object with the methods fnMessageReceived(iMessage), fnMessageSent(iMessage), fnConnectionOpened(), fnConnectionClosed() and fnExceptionCaught().
3564 		 * @example
3565 		 * //NOTE: The following code registers an anonymous listener, that can not later be removed.
3566 		 * //In order to be able to remove a listener, keep a reference to it and then pass that reference to VENISON.NETWORK.NetworkManager.fnRemoveNetworkListener.
3567 		 * VENISON.NETWORK.NetworkManager.fnAddNetworkListener({
3568 		 *		fnMessageReceived: function (iMessage) {
3569 		 *			//Do something
3570 		 *		},
3571 		 *		fnMessageSent: function (iMessage) {
3572 		 *			//Do something
3573 		 *		},
3574 		 *		fnConnectionOpened: function () {
3575 		 *			//Do something
3576 		 *		},
3577 		 *		fnConnectionClosed: function () {
3578 		 *			//Do something
3579 		 *		},
3580 		 *		fnExceptionCaught: function (iException) {
3581 		 *			//Do something
3582 		 *		}
3583 		 * });
3584 		 *
3585 		 */
3586 		this.fnAddNetworkListener = function (iListener) {
3587 			if ('id' in iListener) {
3588 				throw "Cannot add listener already registered in VENISON.NETWORK.NetworkManager";
3589 			}
3590 			iListener.id = mListeners.length;
3591 			mListeners.push(iListener);
3592 
3593 		}
3594 		/**
3595 		 * Function to remove a previously added network listener.
3596 		 * @methodOf VENISON.NETWORK.NetworkManager.prototype
3597 		 * @name fnRemoveNetworkListener
3598 		 * @param {Object} iListener The listener to be removed.
3599 		 * @see VENISON.NETWORK.NetworkManager#fnAddNetworkListener
3600 		 */
3601 		this.fnRemoveNetworkListener = function (iListener) {
3602 			if (!('id' in iListener)) {
3603 				throw "Cannot remove listener NOT already registered in VENISON.NETWORK.NetworkManager";
3604 			}
3605 			var lastListener = mListeners[mListeners.length-1];
3606 			mListeners[iListener.id] = lastListener;
3607 			mListeners.pop();
3608 			delete iListener.id;
3609 		}
3610 		/**
3611 		 * Connect to socket.io on the node.js (http://nodejs.org) server running on the server machine, on the specified port.
3612 		 * @methodOf VENISON.NETWORK.NetworkManager.prototype
3613 		 * @name fnConnect
3614 		 * @param {Number} iPort The port number on which the node.js server is listening.
3615 		 * @see VENISON.NETWORK.NetworkManager#fnDisconnect
3616 		 */
3617 		this.fnConnect = function (iPort) {
3618 			try {
3619 				mSocket = new io.Socket();
3620 				mSocket.options.port = iPort;
3621 				mSocket.connect();
3622 				mSocket.on('connect', mfnConnectionOpened);
3623 				mSocket.on('message', mfnMessageReceived);
3624 				mSocket.on('disconnect', mfnConnectionClosed);
3625 				mSocket.on('error', mfnExceptionCaught)
3626 
3627 			} catch (exception) {
3628 				mfnExceptionCaught(exception);
3629 			}
3630 		}
3631 		/**
3632 		 * Disconnect from socket.io on the node.js (http://nodejs.org) server running on the server machine.
3633 		 * @methodOf VENISON.NETWORK.NetworkManager.prototype
3634 		 * @name fnDisconnect
3635 		 * @see VENISON.NETWORK.NetworkManager#fnConnect
3636 		 */
3637 		this.fnDisconnect = function () {
3638 			mSocket.disconnect();
3639 		}
3640 		/**
3641 		 * Send a message to socket.io on the node.js (http://nodejs.org) server running on the server machine.
3642 		 * @param {Object} iMessage The message to send (could be any JavaScript object).
3643 		 * @methodOf VENISON.NETWORK.NetworkManager.prototype
3644 		 * @name fnSendMessage
3645 		 * @see VENISON.NETWORK.NetworkManager#fnConnect
3646 		 * @see VENISON.NETWORK.NetworkManager#fnDisconnect
3647 		 */
3648 		this.fnSendMessage = function (iMessage) {
3649 			try {
3650 				mSocket.send(iMessage);
3651 				mfnMessageSent(iMessage);
3652 			} catch (exception) {
3653 				mfnExceptionCaught(exception);
3654 			}
3655 		}
3656 	}
3657 })();
3658 (function () {
3659 	var GameEntity = VENISON.ENTITY.GameEntity;
3660 	var Transformation = VENISON.UTILITIES.Transformation;
3661 	var PropertyFactory = VENISON.PROPERTY.PropertyFactory;
3662 	var EntityManager = VENISON.ENTITY.EntityManager;
3663 	var PhysicsManager = VENISON.PHYSICS.PhysicsManager;
3664 	var FocusManager = VENISON.GENERAL.FocusManager;
3665 
3666 	/**
3667 	 * @class A singleton with methods to load and unload levels,
3668 	 * as well as copying and pasting entities and extracting XML-data from the current level, etc.
3669 	 *
3670 	 */
3671 	VENISON.TOOLS.LevelLoader = new function () {
3672 
3673 		function mfnParseNodeValue(iNodeValue) {
3674 			var len = iNodeValue.length;
3675 			if((iNodeValue.charAt(0) === "'" || iNodeValue.charAt(0) === '"') && (iNodeValue.charAt(len-1) === "'" || iNodeValue.charAt(len-1) === '"')) {
3676 				return unescape(iNodeValue.substring(1,len-1));
3677 			}
3678 			if(iNodeValue === "true") {
3679 				return true;
3680 			}
3681 			if(iNodeValue === "false") {
3682 				return false;
3683 			}
3684 			var num = Number(iNodeValue);
3685 			if(!isNaN(num)) {
3686 				return num;
3687 			}
3688 			return unescape(iNodeValue);
3689 		}
3690 
3691 		function mfnGetAttributes(propertyElement) {
3692 			var children = propertyElement.childNodes;
3693 			if (children.length === 0) {//If the property has no attributes what so ever
3694 				return {};
3695 			}
3696 			if (children.length === 1 && children[0].childNodes.length === 0) {//If we have reached a "leaf-attribute" (the attributes value is the actual leaf in the tree)
3697 
3698 				return mfnParseNodeValue(children[0].nodeValue);
3699 			}
3700 
3701 			var childElements = VENISON.UTILITIES.gfnGetChildElements(propertyElement);
3702 
3703 			var result = {};
3704 			var childElementsLength = childElements.length;
3705 			for (var i = 0; i < childElementsLength; i ++) {
3706 				result[childElements[i].tagName] = mfnGetAttributes(childElements[i]);
3707 			}
3708 			return result;
3709 		}
3710 
3711 		function mfnLoadLevelFromXMLDoc(iXMLDoc) {
3712 
3713 			// begin INIT WORLD begin
3714 			var worldValues = iXMLDoc.getElementsByTagName("world")[0];
3715 			var top = parseFloat(worldValues.getElementsByTagName("top")[0].firstChild.nodeValue);
3716 			var left = parseFloat(worldValues.getElementsByTagName("left")[0].firstChild.nodeValue);
3717 			var width = parseFloat(worldValues.getElementsByTagName("width")[0].firstChild.nodeValue);
3718 			var height = parseFloat(worldValues.getElementsByTagName("height")[0].firstChild.nodeValue);
3719 			var gravityX = parseFloat(worldValues.getElementsByTagName("gravityX")[0].firstChild.nodeValue);
3720 			var gravityY = parseFloat(worldValues.getElementsByTagName("gravityY")[0].firstChild.nodeValue);
3721 			VENISON.PHYSICS.PhysicsManager.fnInitialize(top, left, width, height, gravityX, gravityY);
3722 			//end INIT WORLD end
3723 
3724 			mfnAddEntitiesFromXML(iXMLDoc);
3725 
3726 			var nameNode = iXMLDoc.getElementsByTagName("inputfocus")[0].firstChild;
3727 			if(nameNode) {
3728 				var focusEntityName = unescape(nameNode.nodeValue);
3729 				if(focusEntityName) {
3730 					var focusedEntity = EntityManager.fnGetEntityByName(focusEntityName);
3731 					if(focusedEntity) {
3732 						FocusManager.fnSetInputFocusEntityID(focusedEntity.id);
3733 					} else {
3734 						log("No entity with name '"+ focusEntityName + "', input focus not set!");
3735 					}
3736 				}
3737 			}
3738 
3739 			nameNode = iXMLDoc.getElementsByTagName("camerafocus")[0].firstChild;
3740 			if(nameNode) {
3741 				focusEntityName = unescape(nameNode.nodeValue);
3742 				if(focusEntityName) {
3743 					focusedEntity = EntityManager.fnGetEntityByName(focusEntityName);
3744 					if(focusedEntity) {
3745 						FocusManager.fnSetCameraFocusEntityID(focusedEntity.id);
3746 					} else {
3747 						log("No entity with name '"+ focusEntityName + "', camera focus not set!");
3748 					}
3749 				}
3750 			}
3751 
3752 			var camPos = VENISON.GRAPHICS.GraphicsManager.fnGetCameraByName('default').transformation.position;
3753 			camPos.x = camPos.y = 0;
3754 
3755 			EntityManager.fnOnLevelLoaded();
3756 
3757 		}
3758 
3759 		/**
3760 		 * Loads a level from an xml-file located on the server.
3761 		 * The level described within the file with name iLevelFileName in the level directory on the server is loaded into the world.
3762 		 * NOTE: The previous level is not unloaded, the new entities are simply added after the existing ones.
3763 		 * @methodOf VENISON.TOOLS.LevelLoader.prototype
3764 		 * @name fnLoadLevelFromFile
3765 		 * @param {String} iLevelFileName The name of a file existing in the level directory on the server. Example: 'meatfactory_1337.xml' is similar to 'meatfactory_1337', since it is implied that the file is of xml type.
3766 		 * @returns {Object} The xml-DOM created from the file.
3767 		 */
3768 		this.fnLoadLevelFromFile = function (iLevelFileName) {
3769 			if (iLevelFileName.split('.').pop() != 'xml') {
3770 				iLevelFileName += '.xml';
3771 			}
3772 			if (iLevelFileName.split('/')[0] != VENISON.VARS.levelsDir) {
3773 				iLevelFileName = VENISON.VARS.levelsDir + '/' + iLevelFileName;
3774 			}
3775 			var xmlhttp = new XMLHttpRequest();
3776 			xmlhttp.open("GET",iLevelFileName,false);
3777 			xmlhttp.setRequestHeader('Cache-Control', 'no-cache');
3778 			xmlhttp.send();
3779 			return this.fnLoadLevelFromString(xmlhttp.responseText);
3780 		}
3781 		/**
3782 		 * Loads a level from an xml-string.
3783 		 * NOTE: The previous level is not unloaded, the new entities are simply added after the existing ones.
3784 		 * @methodOf VENISON.TOOLS.LevelLoader.prototype
3785 		 * @name fnLoadLevelFromString
3786 		 * @param {String} iLevelString The string in xml-format describing the level.
3787 		 * @returns {Object} The xml-DOM created from the string.
3788 		 */
3789 		this.fnLoadLevelFromString = function (iLevelString) {
3790 			var xmlDoc = VENISON.UTILITIES.gfnGetDOMFromXMLString(iLevelString);
3791 			mfnLoadLevelFromXMLDoc(xmlDoc);
3792 			return xmlDoc;
3793 		}
3794 		//@returns the entities that were added to the level
3795 		function mfnAddEntitiesFromXML(iXMLDoc) {
3796 			var result = [];
3797 			var entities = iXMLDoc.getElementsByTagName("entity");
3798 			var entitiesLength = entities.length;
3799 			for(var i = 0; i < entitiesLength; i++) {//Loop through all entities
3800 
3801 				var entityTransformation = entities[i].getElementsByTagName("transformation")[0];
3802 				if(!entityTransformation) {
3803 					alert("No transformation attribute found in entity nr: " + i); // An entity must have a transformation attribute
3804 					continue;
3805 				}
3806 
3807 				//Create the entity
3808 				var newGameEntity = new GameEntity();
3809 				EntityManager.fnRegisterEntity(newGameEntity);
3810 				result.push(newGameEntity);
3811 
3812 				//get the name
3813 				var nameElems  = entities[i].getElementsByTagName("name");
3814 				if (nameElems.length) {
3815 					var name = unescape(nameElems[0].firstChild.nodeValue);
3816 					newGameEntity.fnSetName(name);
3817 				}
3818 
3819 				var newTransformation = new Transformation();
3820 
3821 				var xArray = entityTransformation.getElementsByTagName("x");
3822 				var yArray = entityTransformation.getElementsByTagName("y");
3823 
3824 				newTransformation.position.x = parseFloat(xArray[0].firstChild.nodeValue);
3825 				newTransformation.position.y = parseFloat(yArray[0].firstChild.nodeValue);
3826 				newTransformation.rotation = parseFloat(entityTransformation.getElementsByTagName("rotation")[0].firstChild.nodeValue);
3827 				newTransformation.scale.x = parseFloat(xArray[1].firstChild.nodeValue);
3828 				newTransformation.scale.y = parseFloat(yArray[1].firstChild.nodeValue);
3829 				newGameEntity.transformation = newTransformation;
3830 
3831 				var propertiesElement = entities[i].getElementsByTagName("properties")[0];
3832 				if(propertiesElement) { //Does this entity have any properties?
3833 					var properties = VENISON.UTILITIES.gfnGetChildElements(propertiesElement); // Find all properties
3834 					var propertiesLength = properties.length;
3835 					for(var j = 0; j < propertiesLength; j++) {
3836 
3837 						var propertyAttributes = mfnGetAttributes(properties[j]);
3838 						//Create the property
3839 						var newProperty = PropertyFactory.fnCreateProperty(unescape(properties[j].nodeName), propertyAttributes);
3840 						newGameEntity.fnAttachProperty(newProperty);
3841 					}//Property loop end
3842 				}
3843 			}//Entity loop end
3844 			return result;
3845 		}
3846 
3847 		/**
3848 		 * @param iUseEntityAttributes if true use the attributes of the entity, else use the attributes of the entity's properties
3849 		 * @ignore
3850 		 */
3851 		function mfnAppendEntitiesToXML(iXMLDoc, iEntities, iUseEntityAttributes) {
3852 			var entitiesLength = iEntities.length;
3853 			for(var i = 0; i < entitiesLength; i++) {
3854 				var entity = iEntities[i];
3855 				if (entity) {
3856 					var newEntityElement = iXMLDoc.createElement("entity");
3857 					iXMLDoc.documentElement.appendChild(newEntityElement);
3858 
3859 					if (entity.fnGetName()) {
3860 						var nameElement = iXMLDoc.createElement("name");
3861 						newEntityElement.appendChild(nameElement);
3862 						nameElement.appendChild(iXMLDoc.createTextNode(escape(entity.fnGetName())));
3863 					}
3864 
3865 					var transformElement = iXMLDoc.createElement("transformation");
3866 					newEntityElement.appendChild(transformElement);
3867 					mfnCreateAttributeHierarchy(iXMLDoc, transformElement, entity.transformation);
3868 
3869 					var propertiesElement = iXMLDoc.createElement("properties");
3870 					newEntityElement.appendChild(propertiesElement);
3871 
3872 					var properties = entity.fnGetProperties();
3873 					var propertiesLength = properties.length;
3874 					for(var j = 0; j < propertiesLength; j++) {
3875 						var newPropertyElement = iXMLDoc.createElement(escape(properties[j].fnGetName()));
3876 						propertiesElement.appendChild(newPropertyElement);
3877 
3878 						mfnCreateAttributeHierarchy(iXMLDoc, newPropertyElement, properties[j].attributes, iUseEntityAttributes ? entity.attributes : null);
3879 					}
3880 				}
3881 			}
3882 		}
3883 
3884 		/**
3885 		 * Create an xml-DOM from in-world entities, by copying either the current values of their attributes or the default values of their properties' attributes.
3886 		 * @methodOf VENISON.TOOLS.LevelLoader.prototype
3887 		 * @name fnCopyEntities
3888 		 * @param {Array} iEntities An array of {@link VENISON.ENTITY.GameEntity}.
3889 		 * @param {Boolean} iUseEntityAttributes true if the current values of the entities' attributes should be copied, false if the default values of their properties' attributes should be used.
3890 		 * @returns {Object} A pointer to an xml-DOM describing the entities, preferably to be passed as an argument to {@link VENISON.TOOLS.LevelLoader#fnPasteEntities}.
3891 		 */
3892 		this.fnCopyEntities = function(iEntities, iUseEntityAttributes) {
3893 			var xmlDoc = VENISON.UTILITIES.gfnGetDOMFromXMLString("<root />");
3894 			mfnAppendEntitiesToXML(xmlDoc, iEntities, iUseEntityAttributes);
3895 			return xmlDoc;
3896 		}
3897 		/**
3898 		 * Insert entities in xml-form into the world.
3899 		 * @methodOf VENISON.TOOLS.LevelLoader.prototype
3900 		 * @name fnPasteEntities
3901 		 * @param {Object} iXMLRoot a pointer to the root of an XML DOM object containing entities, as returned by {@link VENISON.TOOLS.LevelLoader#fnCopyEntities}.
3902 		 * @returns {Array} An array of {@link VENISON.ENTITY.GameEntity} inserted into the world.
3903 		 */
3904 		this.fnPasteEntities = function (iXMLRoot) {
3905 			return mfnAddEntitiesFromXML(iXMLRoot);
3906 		}
3907 		function mfnCreateAttributeHierarchy(iXMLDoc, iRootElement, iPropertyAttributes, iEntityAttributes) {
3908 			for (var attr in iPropertyAttributes) {
3909 				if(iPropertyAttributes[attr] instanceof Function) {
3910 					continue; //We don't want to add functions as elements in the xml
3911 				}
3912 				var newElement = iXMLDoc.createElement(escape(attr));
3913 				iRootElement.appendChild(newElement);
3914 
3915 				if (!(iPropertyAttributes[attr] instanceof Object)) {
3916 					var textNode = iXMLDoc.createTextNode('');
3917 					var value = iEntityAttributes ? iEntityAttributes[attr] : iPropertyAttributes[attr]; //It's the attribute of the entity that is relevant
3918 					if(value === true) {
3919 						textNode.nodeValue = "true";
3920 					} else if(value === false) {
3921 						textNode.nodeValue = "false";
3922 					} else {
3923 						var num = Number(value);
3924 						if(!isNaN(num)) {
3925 							textNode.nodeValue = num + '';
3926 						} else {
3927 							textNode.nodeValue = '"' + escape(value) + '"';
3928 						}
3929 					}
3930 					newElement.appendChild(textNode);
3931 				} else {
3932 					mfnCreateAttributeHierarchy(iXMLDoc, newElement, iPropertyAttributes[attr], iEntityAttributes ? iEntityAttributes[attr] : null);
3933 				}
3934 			}
3935 		}
3936 
3937 		/**
3938 		 * Function useful to save the current level etc.
3939 		 * @methodOf VENISON.TOOLS.LevelLoader.prototype
3940 		 * @name fnGetXMLStringFromCurrentLevel
3941 		 * @param {Boolean} iUseEntityAttributes If true, the attributes values are taken from the entity to which they belong,
3942 		 * otherwise they are taken from the default values of the corresponding properties.
3943 		 * Example: A player has an 'extraLives' attribute, defined by a property in which it's default value is 3.
3944 		 * However, the player has died 2 times, so the value of the entity's attribute is now 1.
3945 		 * If this parameter is set to true, the 'extraLives' attribute of the returned entity would have the value 1,
3946 		 *  otherwise it would have the value 3, as it would use the default value defined in the property.
3947 		 * @returns {String} A string containing an XML-structure describing the current state of the level.
3948 		 */
3949 		this.fnGetXMLStringFromCurrentLevel = function(iUseEntityAttributes) {
3950 			var xmlDoc = VENISON.UTILITIES.gfnGetDOMFromXMLString("<level />");
3951 
3952 			var entities = EntityManager.fnGetEntities();
3953 
3954 			mfnAppendEntitiesToXML(xmlDoc, entities, iUseEntityAttributes);
3955 
3956 			//Create input & camera focus elements and physicsworld elements.
3957 			var inputFocus = xmlDoc.createElement("inputfocus");
3958 			var cameraFocus = xmlDoc.createElement("camerafocus");
3959 
3960 			var focusID = FocusManager.fnGetInputFocusEntityID();
3961 			if (focusID !== null) {
3962 				var focusEntity = EntityManager.fnGetEntityByID(focusID);
3963 				var focusName = escape(focusEntity.fnGetName());
3964 				if (focusName) {
3965 					inputFocus.appendChild(xmlDoc.createTextNode(focusName));
3966 				} else {
3967 					log('Input focus entity has no name and will not be written to the level!');
3968 				}
3969 			}
3970 
3971 			focusID = FocusManager.fnGetCameraFocusEntityID();
3972 			if (focusID !== null) {
3973 				var focusEntity = EntityManager.fnGetEntityByID(focusID);
3974 				var focusName = escape(focusEntity.fnGetName());
3975 				if (focusName) {
3976 					cameraFocus.appendChild(xmlDoc.createTextNode(focusName));
3977 				} else {
3978 					log('Camera focus entity has no name and will not be written to the level!');
3979 				}
3980 			}
3981 
3982 			xmlDoc.documentElement.appendChild(inputFocus);
3983 			xmlDoc.documentElement.appendChild(cameraFocus);
3984 
3985 			var worldVars = xmlDoc.createElement("world");
3986 			var wVar = xmlDoc.createElement('top');
3987 			wVar.appendChild(xmlDoc.createTextNode(0));//DUMMY
3988 			worldVars.appendChild(wVar);
3989 
3990 			wVar = xmlDoc.createElement('left');
3991 			wVar.appendChild(xmlDoc.createTextNode(0));//DUMMY
3992 			worldVars.appendChild(wVar);
3993 
3994 			wVar = xmlDoc.createElement('width');
3995 			wVar.appendChild(xmlDoc.createTextNode(0));//DUMMY
3996 			worldVars.appendChild(wVar);
3997 
3998 			wVar = xmlDoc.createElement('height');
3999 			wVar.appendChild(xmlDoc.createTextNode(0));//DUMMY
4000 			worldVars.appendChild(wVar);
4001 
4002 			var gravity = VENISON.PHYSICS.PhysicsManager.fnGetGravity();
4003 
4004 			wVar = xmlDoc.createElement('gravityX');
4005 			wVar.appendChild(xmlDoc.createTextNode(gravity.x));
4006 			worldVars.appendChild(wVar);
4007 
4008 			wVar = xmlDoc.createElement('gravityY');
4009 			wVar.appendChild(xmlDoc.createTextNode(gravity.y));
4010 			worldVars.appendChild(wVar);
4011 
4012 			xmlDoc.documentElement.appendChild(worldVars);
4013 
4014 			return VENISON.UTILITIES.gfnGetXMLStringFromDOM(xmlDoc);
4015 		}
4016 		/**
4017 		 * Unload the current level. After this call, the game world will be empty.
4018 		 * @methodOf VENISON.TOOLS.LevelLoader.prototype
4019 		 * @name fnUnloadCurrentLevel
4020 		 */
4021 		this.fnUnloadCurrentLevel = function () {
4022 			EntityManager.fnOnLevelUnloaded();
4023 			FocusManager.fnOnLevelUnloaded();
4024 			PhysicsManager.fnOnLevelUnloaded();
4025 		}
4026 	}
4027 })();
4028 (function () {
4029 	var paused = false;
4030 	/**
4031 	 * The method to start the Venison Engine main loop, responsible of updating all systems.
4032 	 * @function
4033 	 * @param {String} iMainCanvasId The id of the main game canvas as defined in the html-file.
4034 	 * @param {Number} iFPS The desired frame rate of the simulation, in frames per second.
4035 	 * @param {Boolean} iUseWebGL2D If set to any non-false value, the experimental WebGL2D will be used for rendering, if the browser supports WebGL.
4036 	 */
4037 	VENISON.fnStart = function (iMainCanvasId, iFPS, iUseWebGL2D) {
4038 		var GameStateManager = VENISON.GAMESTATES.GameStateManager;
4039 		var FocusManager = VENISON.GENERAL.FocusManager;
4040 		var EntityManager = VENISON.ENTITY.EntityManager;
4041 		var PhysicsManager = VENISON.PHYSICS.PhysicsManager;
4042 		var InputManager = VENISON.GENERAL.InputManager;
4043 		var GraphicsManager = VENISON.GRAPHICS.GraphicsManager;
4044 		var AudioManager = VENISON.AUDIO.AudioManager;
4045 		var AnimationManager = VENISON.GRAPHICS.AnimationManager;
4046 		var MessageManager = VENISON.MESSAGES.MessageManager;
4047 
4048 		var mDesiredFrameTime = 1000/iFPS;
4049 		var mTimeStep = 1/iFPS;
4050 		var overTime = 0;
4051 		function gfnMainGameLoop() {
4052 			var frameStartTime = (new Date()).getTime();
4053 			if (!paused) {
4054 				GameStateManager.fnUpdate();
4055 				FocusManager.fnUpdate();
4056 				EntityManager.fnUpdate();
4057 				AudioManager.fnUpdate();
4058 				PhysicsManager.fnUpdate(mTimeStep);
4059 				AnimationManager.fnUpdate();
4060 				InputManager.fnUpdate();
4061 				MessageManager.fnUpdate();
4062 
4063 				var frameTimeTaken = (new Date()).getTime() - frameStartTime;
4064 				var timeLeft = mDesiredFrameTime - frameTimeTaken;
4065 				if (timeLeft > overTime) {
4066 					GraphicsManager.fnUpdate();
4067 					if (PhysicsManager.renderDebugInfo) {
4068 						PhysicsManager.fnRender(GraphicsManager.fnGetCameraByName('default').fnGetContext());
4069 					}
4070 				}
4071 			}
4072 			frameTimeTaken = (new Date()).getTime() - frameStartTime;
4073 			timeLeft = mDesiredFrameTime - frameTimeTaken;
4074 			overTime = 0;
4075 			if (timeLeft < 0) {
4076 				overTime = -timeLeft;
4077 				timeLeft = 0;
4078 			}
4079 			setTimeout(gfnMainGameLoop, timeLeft);
4080 		}
4081 
4082 		//Get and store the main canvas
4083 		var mc = document.getElementById(iMainCanvasId);
4084 		VENISON.VARS.mainCanvas = mc;
4085 		VENISON.GRAPHICS.HUDManager.fnPositionHUD(); //make the hud cover the canvas
4086 
4087 		//Create the default camera
4088 		var defaultCamera = new VENISON.GRAPHICS.Camera(mc, iUseWebGL2D);
4089 
4090 		GraphicsManager.fnRegisterCameraWithName(defaultCamera, 'default');
4091 
4092 		gfnMainGameLoop();
4093 
4094 	};
4095 	/**
4096 	 * Method to pause and unpause the whole venison engine game loop. Remember that not even the gamestates will be updated when paused, so the unpausing has to be a little inventive.
4097 	 * @function
4098 	 * @param {Boolean} iPaused true to pause, false to unpause.
4099 	 */
4100 	VENISON.fnSetPaused = function (iPaused) {
4101 		paused = iPaused;
4102 	}
4103 	/**
4104 	 * @deprecated Use VENISON.fnStart instead.
4105 	 * @function
4106 	 */
4107 	VENISON.Start = function (iMainCanvasId, iFPS, iUseWebGL2D) {
4108 		VENISON.fnStart(iMainCanvasId, iFPS, iUseWebGL2D);
4109 	}
4110 })();