UNPKG

lettuce

Version:

Lettuce JS, Mini Mobile Framework for Romantic with DSL.

195 lines (183 loc) 7.61 kB
/* * MelonJS Game Engine * Copyright (C) 2011 - 2013, Olivier Biot * http://www.melonjs.org * */ (function () { /** * A pool of Object entity <br> * This object is used for object pooling - a technique that might speed up your game * if used properly. <br> * If some of your classes will be instantiated and removed a lot at a time, it is a * good idea to add the class to this entity pool. A separate pool for that class * will be created, which will reuse objects of the class. That way they won't be instantiated * each time you need a new one (slowing your game), but stored into that pool and taking one * already instantiated when you need it.<br><br> * This object is also used by the engine to instantiate objects defined in the map, * which means, that on level loading the engine will try to instantiate every object * found in the map, based on the user defined name in each Object Properties<br> * <img src="images/object_properties.png"/><br> * @namespace me.pool * @memberOf me */ me.pool = (function () { // hold public stuff in our singleton var api = {}; var entityClass = {}; /* * PUBLIC STUFF */ /** * Constructor * @ignore */ api.init = function () { // add default entity object api.register("me.Entity", me.Entity); api.register("me.CollectableEntity", me.CollectableEntity); api.register("me.LevelEntity", me.LevelEntity); api.register("TileObject", me.Sprite); api.register("me.Tween", me.Tween, true); api.register("me.Color", me.Color, true); api.register("me.Particle", me.Particle, true); }; /** * register an object to the pool. <br> * Pooling must be set to true if more than one such objects will be created. <br> * (note) If pooling is enabled, you shouldn't instantiate objects with `new`. * See examples in {@link me.pool#pull} * @name register * @memberOf me.pool * @public * @function * @param {String} className as defined in the Name field of the Object Properties (in Tiled) * @param {Object} class corresponding Class to be instantiated * @param {Boolean} [objectPooling=false] enables object pooling for the specified class * - speeds up the game by reusing existing objects * @example * // add our users defined entities in the entity pool * me.pool.register("playerspawnpoint", PlayerEntity); * me.pool.register("cherryentity", CherryEntity, true); * me.pool.register("heartentity", HeartEntity, true); * me.pool.register("starentity", StarEntity, true); */ api.register = function (className, entityObj, pooling) { if (!pooling) { entityClass[className.toLowerCase()] = { "class" : entityObj, "pool" : undefined }; return; } entityClass[className.toLowerCase()] = { "class" : entityObj, "pool" : [] }; }; /** * Pull a new instance of the requested object (if added into the object pool) * @name pull * @memberOf me.pool * @public * @function * @param {String} className as used in {@link me.pool#register} * @param {} [arguments...] arguments to be passed when instantiating/reinitializing the object * @example * me.pool.register("player", PlayerEntity); * var player = me.pool.pull("player"); * @example * me.pool.register("bullet", BulletEntity, true); * me.pool.register("enemy", EnemyEntity, true); * // ... * // when we need to manually create a new bullet: * var bullet = me.pool.pull("bullet", x, y, direction); * // ... * // params aren't a fixed number * // when we need new enemy we can add more params, that the object construct requires: * var enemy = me.pool.pull("enemy", x, y, direction, speed, power, life); * // ... * // when we want to destroy existing object, the remove * // function will ensure the object can then be reallocated later * me.game.world.removeChild(enemy); * me.game.world.removeChild(bullet); */ api.pull = function (data) { var name = typeof data === "string" ? data.toLowerCase() : undefined; var args = []; for (var i = 0; i < arguments.length; i++) { args.push(arguments[i]); } if (name && entityClass[name]) { var proto; if (!entityClass[name].pool) { proto = entityClass[name]["class"]; args[0] = proto; return new (proto.bind.apply(proto, args))(); } var obj, entity = entityClass[name]; proto = entity["class"]; if (entity.pool.length > 0) { obj = entity.pool.pop(); args.shift(); // call the object init function if defined (JR's Inheritance) if (typeof obj.init === "function") { obj.init.apply(obj, args); } // call the object onResetEvent function if defined if (typeof obj.onResetEvent === "function") { obj.onResetEvent.apply(obj, args); } } else { args[0] = proto; obj = new (proto.bind.apply(proto, args))(); obj.className = name; } return obj; } if (name) { console.error("Cannot instantiate entity of type '" + data + "': Class not found!"); } return null; }; /** * purge the entity pool from any inactive object <br> * Object pooling must be enabled for this function to work<br> * note: this will trigger the garbage collector * @name purge * @memberOf me.pool * @public * @function */ api.purge = function () { for (var className in entityClass) { if (entityClass.hasOwnProperty(className)) { entityClass[className].pool = []; } } }; /** * Push back an object instance into the entity pool <br> * Object pooling for the object class must be enabled, * and object must have been instantiated using {@link me.pool#pull}, * otherwise this function won't work * @name push * @memberOf me.pool * @public * @function * @param {Object} instance to be recycled */ api.push = function (obj) { var name = obj.className; if (typeof(name) === "undefined" || !entityClass[name]) { // object is not registered, don't do anything return; } // store back the object instance for later recycling entityClass[name].pool.push(obj); }; // return our object return api; })(); })();