UNPKG

lettuce

Version:

Lettuce JS, Mini Mobile Framework for Romantic with DSL.

309 lines (257 loc) 9.02 kB
/** * MelonJS Game Engine * (C) 2011 - 2014 Olivier Biot, Jason Oster, Aaron McLeod * http://www.melonjs.org */ (function () { /** * me.game represents your current game, it contains all the objects, * tilemap layers, current viewport, collision map, etc...<br> * me.game is also responsible for updating (each frame) the object status * and draw them<br> * @namespace me.game * @memberOf me */ me.game = (function () { // hold public stuff in our singleton var api = {}; /* * PRIVATE STUFF */ // flag to redraw the sprites var initialized = false; // to know when we have to refresh the display var isDirty = true; // frame counter for frameSkipping // reset the frame counter var frameCounter = 0; var frameRate = 1; // reference to the renderer object var renderer = null; /* * PUBLIC STUFF */ /** * a reference to the game viewport. * @public * @type {me.Viewport} * @name viewport * @memberOf me.game */ api.viewport = null; /** * a reference to the game current level * @public * @type {me.TMXTileMap} * @name currentLevel * @memberOf me.game */ api.currentLevel = null; /** * a reference to the game world <br> * a world is a virtual environment containing all the game objects * @public * @type {me.Container} * @name world * @memberOf me.game */ api.world = null; /** * when true, all objects will be added under the root world container<br> * when false, a `me.Container` object will be created for each * corresponding `TMXObjectGroup` * default value : true * @public * @type {boolean} * @name mergeGroup * @memberOf me.game */ api.mergeGroup = true; /** * The property of should be used when sorting entities <br> * value : "x", "y", "z" (default: "z") * @public * @type {string} * @name sortOn * @memberOf me.game */ api.sortOn = "z"; /** * default layer tmxRenderer * @private * @ignore * @type {me.TMXRenderer} * @name tmxRenderer * @memberOf me.game */ api.tmxRenderer = null; /** * Fired when a level is fully loaded and <br> * and all entities instantiated. <br> * Additionnaly the level id will also be passed * to the called function. * @public * @callback * @name onLevelLoaded * @memberOf me.game * @example * // call myFunction () everytime a level is loaded * me.game.onLevelLoaded = this.myFunction.bind(this); */ api.onLevelLoaded = null; /** * Initialize the game manager * @name init * @memberOf me.game * @private * @ignore * @function * @param {Number} [width] width of the canvas * @param {Number} [height] width of the canvas * init function. */ api.init = function (width, height) { if (!initialized) { // if no parameter specified use the system size width = width || me.video.renderer.getWidth(); height = height || me.video.renderer.getHeight(); // create a defaut viewport of the same size api.viewport = new me.Viewport(0, 0, width, height); //the root object of our world is an entity container api.world = new me.Container(0, 0, width, height); // give it a name api.world.name = "rootContainer"; // initialize the collision system (the quadTree mostly) me.collision.init(); renderer = me.video.renderer; // publish init notification me.event.publish(me.event.GAME_INIT); // translate global pointer events me.input._translatePointerEvents(); // make display dirty by default isDirty = true; // dummy current level api.currentLevel = { pos : { x : 0, y : 0 } }; // set as initialized initialized = true; } }; /** * reset the game Object manager<p> * destroy all current objects * @name reset * @memberOf me.game * @public * @function */ api.reset = function () { // clear the quadtree me.collision.quadTree.clear(); // remove all objects api.world.destroy(); // reset the viewport to zero ? if (api.viewport) { api.viewport.reset(); } // dummy current level api.currentLevel = { pos : { x : 0, y : 0 } }; // reset the transform matrix to the normal one renderer.resetTransform(); // reset the frame counter frameCounter = 0; frameRate = ~~(0.5 + 60 / me.sys.fps); }; /** * Returns the parent container of the specified Child in the game world * @name getParentContainer * @memberOf me.game * @function * @param {me.Renderable} child * @return {me.Container} */ api.getParentContainer = function (child) { return child.ancestor; }; /** * force the redraw (not update) of all objects * @name repaint * @memberOf me.game * @public * @function */ api.repaint = function () { isDirty = true; }; /** * update all objects of the game manager * @name update * @memberOf me.game * @private * @ignore * @function * @param {Number} time current timestamp as provided by the RAF callback */ api.update = function (time) { // handle frame skipping if required if ((++frameCounter % frameRate) === 0) { // reset the frame counter frameCounter = 0; // update the timer me.timer.update(time); // clear the quadtree me.collision.quadTree.clear(); // insert the world container (children) into the quadtree me.collision.quadTree.insertContainer(api.world); // update all objects (and pass the elapsed time since last frame) isDirty = api.world.update(me.timer.getDelta()) || isDirty; // update the camera/viewport isDirty = api.viewport.update(me.timer.getDelta()) || isDirty; } }; /** * draw all existing objects * @name draw * @memberOf me.game * @private * @ignore * @function */ api.draw = function () { if (isDirty) { // cache the viewport rendering position, so that other object // can access it later (e,g. entityContainer when drawing floating objects) var translateX = api.viewport.pos.x + ~~api.viewport.offset.x; var translateY = api.viewport.pos.y + ~~api.viewport.offset.y; // translate the world coordinates by default to screen coordinates api.world.transform.translate(-translateX, -translateY); // substract the map offset to current the current pos api.viewport.screenX = translateX - api.currentLevel.pos.x; api.viewport.screenY = translateY - api.currentLevel.pos.y; // prepare renderer to draw a new frame me.video.renderer.prepareSurface(); // update all objects, // specifying the viewport as the rectangle area to redraw api.world.draw(renderer, api.viewport); // translate back api.world.transform.translate(translateX, translateY); // draw our camera/viewport api.viewport.draw(renderer); } isDirty = false; // blit our frame me.video.renderer.blitSurface(); }; // return our object return api; })(); })();