UNPKG

lettuce

Version:

Lettuce JS, Mini Mobile Framework for Romantic with DSL.

303 lines (250 loc) 10.4 kB
/* * MelonJS Game Engine * Copyright (C) 2011 - 2013, Olivier BIOT * http://www.melonjs.org * * a simple debug panel plugin * usage : me.plugin.register(debugPanel, "debug"); * * you can then use me.plugin.debug.show() or me.plugin.debug.hide() * to show or hide the panel, or press respectively the "S" and "H" keys. * * note : * Heap Memory information is available under Chrome when using * the "--enable-memory-info" parameter to launch Chrome */ (function () { // ensure that me.debug is defined me.debug = me.debug || {}; /** * @class * @public * @extends me.plugin.Base * @memberOf me * @constructor */ me.debug.ParticlePanel = me.plugin.Base.extend( /** @scope me.debug.ParticlePanel.prototype */ { /** @private */ init : function () { // call the super constructor this._super(me.plugin.Base, "init"); // minimum melonJS version expected this.version = "2.0.0"; // to hold the debug options // clickable rect area this.area = {}; // panel position and size this.rect = null; // for z ordering // make it ridiculously high this.z = Infinity; // visibility flag this.visible = true; this.rect = new me.Rect(0, me.video.renderer.getHeight() - 60, 200, 60); // set the object GUID value this.GUID = "particledebug-" + me.utils.createGUID(); // set the object entity name this.name = "me.particleDebugPanel"; // persistent this.isPersistent = true; // a floating object this.floating = true; // renderable this.isRenderable = true; // always update, even when not visible this.alwaysUpdate = true; // create a default font, with fixed char width this.font = new me.Font("courier", 10, "white"); // sample points this.frameUpdateTimeSamples = []; this.frameDrawTimeSamples = []; this.updateTimeSamples = []; this.drawTimeSamples = []; this.updateTime = 0; this.drawTime = 0; this.updateTimeAvg = 0; this.drawTimeAvg = 0; this.frameUpdateTimeAvg = 0; this.frameDrawTimeAvg = 0; this.emitterCount = 0; this.particleCount = 0; //patch patch patch ! this.patchSystemFn(); // add the debug panel to the game world me.game.world.addChild(this); }, /** * patch system fn to draw debug information */ patchSystemFn : function () { var _this = this; var now = Date.now; if (window.performance && window.performance.now) { now = window.performance.now.bind(window.performance); } // patch me.ParticleEmitter.init me.plugin.patch(me.ParticleEmitter, "init", function (x, y, image) { this._patched(x, y, image); _this.emitterCount++; }); // patch me.ParticleEmitter.destroy me.plugin.patch(me.ParticleEmitter, "destroy", function () { this._patched(); _this.emitterCount--; }); // patch me.Particle.init me.plugin.patch(me.Particle, "init", function (emitter) { this._patched(emitter); _this.particleCount++; }); // patch me.Particle.destroy me.Particle.prototype.destroy = function () { _this.particleCount--; }; // patch me.game.update me.plugin.patch(me.game, "update", function (dt) { var startTime = now(); this._patched(dt); // calculate the update time (can't we use [dt] here ?) _this.frameUpdateTimeSamples.push(now() - startTime); }); // patch me.game.draw me.plugin.patch(me.game, "draw", function () { var startTime = now(); this._patched(); // calculate the drawing time _this.frameDrawTimeSamples.push(now() - startTime); }); // patch me.ParticleContainer.update me.plugin.patch(me.ParticleContainer, "update", function (dt) { var startTime = now(); var value = this._patched(dt); // calculate the update time (can't we use [dt] here ?) _this.updateTime += now() - startTime; return value; }); // patch me.ParticleContainer.draw me.plugin.patch(me.ParticleContainer, "draw", function (context, rect) { var startTime = now(); this._patched(context, rect); // calculate the drawing time _this.drawTime += now() - startTime; }); }, /** @private */ update : function () { return true; }, /** * @private */ getBounds : function () { return this.rect; }, /** * @private */ drawGraph : function (renderer) { var updateTimeSamples = this.updateTimeSamples; var drawTimeSamples = this.drawTimeSamples; var frameUpdateTimeSamples = this.frameUpdateTimeSamples; var frameDrawTimeSamples = this.frameDrawTimeSamples; var width = this.rect.width, height = this.rect.height; while (updateTimeSamples.length > width) { updateTimeSamples.shift(); } while (drawTimeSamples.length > width) { drawTimeSamples.shift(); } while (frameUpdateTimeSamples.length > width) { frameUpdateTimeSamples.shift(); } while (frameDrawTimeSamples.length > width) { frameDrawTimeSamples.shift(); } var maxTime = 60, scale = height / maxTime, len = updateTimeSamples.length; var frameTimeLimit = 1000 / me.sys.fps, where = height - frameTimeLimit * scale; renderer.setGlobalAlpha(0.5); renderer.setColor("grey"); renderer.drawLine(0, where, width, where); renderer.setGlobalAlpha(1.0); var updateTimeSum = 0, drawTimeSum = 0, frameUpdateTimeSum = 0, frameDrawTimeSum = 0, update = [], slowUpdate = [], draw = [], slowDraw = []; // prepare data for (var x = 0, updateTime, drawTime, slow; x < len; ++x) { updateTime = updateTimeSamples[x] || 0; drawTime = drawTimeSamples[x] || 0; slow = (updateTime + drawTime > frameTimeLimit); updateTimeSum += updateTime; drawTimeSum += drawTime; frameUpdateTimeSum += frameUpdateTimeSamples[x] || 0; frameDrawTimeSum += frameDrawTimeSamples[x] || 0; updateTime *= scale; update.push(slow ? 0 : updateTime); slowUpdate.push(slow ? updateTime : 0); drawTime = updateTime + drawTime * scale; draw.push(slow ? 0 : drawTime); slowDraw.push(slow ? drawTime : 0); } this.updateTimeAvg = updateTimeSum / len; this.drawTimeAvg = drawTimeSum / len; this.frameUpdateTimeAvg = frameUpdateTimeSum / len; this.frameDrawTimeAvg = frameDrawTimeSum / len; // draw the graph this.fillArea(renderer, width, height, draw, "lightblue"); this.fillArea(renderer, width, height, slowDraw, "lightcoral"); this.fillArea(renderer, width, height, update, "lightgreen"); this.fillArea(renderer, width, height, slowUpdate, "lightsalmon"); renderer.setGlobalAlpha(1.0); }, /** * @private */ fillArea : function (renderer, width, height, data, color) { var i, x, y, len = data.length; var context = renderer.getContext(); context.fillStyle = color; context.beginPath(); context.moveTo(width, height); for (i = len; i--;) { x = width - (len - i); y = height - data[i]; context.lineTo(x, y < 0 ? 0 : y); context.lineTo(x - 1, y < 0 ? 0 : y); } context.lineTo(0, height); context.closePath(); context.fill(); }, /** @private */ draw : function (renderer) { renderer.save(); // draw the panel renderer.setGlobalAlpha(0.5); renderer.setColor("black"); renderer.fillRect(this.rect.left, this.rect.top, this.rect.width, this.rect.height); renderer.setGlobalAlpha(1.0); renderer.translate(this.rect.left, this.rect.top); // # entities / draw var context = renderer.getContext(); this.font.draw(context, "emitters : " + this.emitterCount, 5, 5); this.font.draw(context, "particles : " + this.particleCount, 5, 18); // draw the update duration this.font.draw(context, "update: " + this.updateTimeAvg.toFixed(2) + "ms / " + this.frameUpdateTimeAvg.toFixed(2) + "ms", 5, 31); // draw the draw duration this.font.draw(context, "draw: " + this.drawTimeAvg.toFixed(2) + "ms / " + this.frameDrawTimeAvg.toFixed(2) + "ms", 5, 44); this.updateTimeSamples.push(this.updateTime); this.updateTime = 0; this.drawTimeSamples.push(this.drawTime); this.drawTime = 0; // draw the graph this.drawGraph(renderer); renderer.restore(); }, }); /*---------------------------------------------------------*/ // END END END /*---------------------------------------------------------*/ })();