%PDF- %PDF-
Direktori : /home/infra/jogos/blocos-1/ext/ |
Current File : //home/infra/jogos/blocos-1/ext/stage-p2.js |
/** * P2.js viewer for Stage.js */ (function() { Stage.P2 = Viewer; Viewer._super = Stage; Viewer.prototype = Stage._create(Viewer._super.prototype); function Viewer(world, options) { Viewer._super.call(this); this.label('P2'); var self = this; this.world = world; this.options = { maxSubSteps : 3, timeStep : 1 / 60, debug : false, debugPolygons : false, lineWidth : 0.025, lineColor : '#000000', fillColor : function() { var red = Stage.Math.random(192, 256) | 0; var green = Stage.Math.random(192, 256) | 0; var blue = Stage.Math.random(192, 256) | 0; return "#" + red.toString(16) + green.toString(16) + blue.toString(16); }, ratio : 128, get : function(key) { var value = this[key]; return typeof value === 'function' ? value() : value; }, extend : function(options) { return Stage._extend({}, this, options); } }.extend(options); world.on("addBody", function(e) { self.addRenderable(e.body); }).on("removeBody", function(e) { self.removeRenderable(e.body); }).on("addSpring", function(e) { self.addRenderable(e.spring); }).on("removeSpring", function(e) { self.removeRenderable(e.spring); }); this.drawContacts = false; this.toggleContact = function(toggle) { if (arguments.length) { this.drawContacts = toggle; } else { this.drawContacts = !this.drawContacts; } return this; }; // Add initial bodies for (var i = 0; i < world.bodies.length; i++) { this.addRenderable(world.bodies[i]); } for (var i = 0; i < world.springs.length; i++) { this.addRenderable(world.springs[i]); } this.tick(function(t) { this.step(1 / 60, t / 1000); }); this.tempv = p2.vec2.fromValues(0, 0); } Viewer.prototype.step = function(t) { this.world.step(this.options.timeStep, t, this.options.maxSubSteps); for (var i = 0; i < this.world.bodies.length; i++) { var body = this.world.bodies[i]; if (body.ui) { body.ui.pin({ offsetX : body.position[0], offsetY : -body.position[1], rotation : -body.angle }); } } for (var i = 0; i < this.world.springs.length; i++) { var spring = this.world.springs[i]; spring.getWorldAnchorA(this.tempv); var ax = this.tempv[0]; var ay = this.tempv[1]; spring.getWorldAnchorB(this.tempv); var bx = this.tempv[0]; var by = this.tempv[1]; // Spring position is the mean point between the anchors var x = (ax + bx) / 2; var y = (ay + by) / 2; // Compute distance vector between anchors, in screen coords var dx = ax - bx; var dy = ay - by; var a = Math.atan2(dx, dy) + Math.PI / 2; var s = Stage.Math.length(dx, dy) / spring.restLength; spring.ui.pin({ offsetX : x, offsetY : -y, scaleX : s, rotation : a }); } }; Viewer.prototype.addRenderable = function(obj) { if (!this.options.debug && typeof obj.ui !== "undefined") { obj.ui && obj.ui.appendTo(this); return; } obj.ui = Stage.create().appendTo(this); if (obj instanceof p2.Body && obj.shapes.length) { if (obj.concavePath && !this.options.debugPolygons) { var texture = this.drawConvex(obj.concavePath, obj.render); Stage.image(texture).appendTo(obj.ui).pin({ handle : 0.5, offsetX : obj.shapeOffsets[i] ? obj.shapeOffsets[i][0] : 0, offsetY : -(obj.shapeOffsets[i] ? obj.shapeOffsets[i][1] : 0), rotation : -obj.shapeAngles[i] || 0 }); } else { for (var i = 0; i < obj.shapes.length; i++) { var shape = obj.shapes[i]; var options = shape.render || obj.render; var texture = null; if (shape instanceof p2.Circle) { texture = this.drawCircle(shape.radius, options); } else if (shape instanceof p2.Particle) { texture = this.drawParticle(options); } else if (shape instanceof p2.Plane) { texture = this.drawPlane(-10, 10, 10, options); } else if (shape instanceof p2.Line) { texture = this.drawLine(shape.length, options); } else if (shape instanceof p2.Rectangle) { texture = this.drawRectangle(shape.width, shape.height, options); } else if (shape instanceof p2.Capsule) { texture = this.drawCapsule(shape.length, shape.radius, options); } else if (shape instanceof p2.Convex) { if (shape.vertices.length) { texture = this.drawConvex(shape.vertices, options); } } Stage.image(texture).appendTo(obj.ui).pin({ handle : 0.5, offsetX : obj.shapeOffsets[i] ? obj.shapeOffsets[i][0] : 0, offsetY : -(obj.shapeOffsets[i] ? obj.shapeOffsets[i][1] : 0), rotation : -obj.shapeAngles[i] || 0 }); } } } else if (obj instanceof p2.Spring) { var texture = this.drawSpring(obj.restLength, obj.render); Stage.image(texture).appendTo(obj.ui).pin({ handle : 0.5 }); } }; Viewer.prototype.removeRenderable = function(obj) { obj.ui && (obj.ui.drop ? obj.ui.drop() : obj.ui.remove()); }; Viewer.prototype.drawLine = function(length, options) { options = this.options.extend(options); var lineWidth = options.get('lineWidth'); var lineColor = options.get('lineColor'); var fillColor = options.get('fillColor'); lineWidth *= 2; var ratio = options.ratio; return Stage.canvas(function(ctx) { this.size(length + 2 * lineWidth, lineWidth, ratio); ctx.scale(ratio, ratio); ctx.moveTo(lineWidth, lineWidth / 2); ctx.lineTo(lineWidth + length, lineWidth / 2); ctx.lineWidth = lineWidth; ctx.lineCap = "round"; ctx.strokeStyle = lineColor; ctx.stroke(); }); }; Viewer.prototype.drawRectangle = function(w, h, options) { options = this.options.extend(options); var lineWidth = options.get('lineWidth'); var lineColor = options.get('lineColor'); var fillColor = options.get('fillColor'); var width = w + 2 * lineWidth; var height = h + 2 * lineWidth; var ratio = options.ratio; return Stage.canvas(function(ctx) { this.size(width, height, ratio); ctx.scale(ratio, ratio); ctx.beginPath(); ctx.rect(lineWidth, lineWidth, w, h); if (fillColor) { ctx.fillStyle = fillColor; ctx.fill(); } ctx.lineWidth = lineWidth; ctx.strokeStyle = lineColor; ctx.stroke(); }); }; Viewer.prototype.drawCircle = function(radius, options) { options = this.options.extend(options); var lineWidth = options.get('lineWidth'); var lineColor = options.get('lineColor'); var fillColor = options.get('fillColor'); var width = radius * 2 + lineWidth * 2; var height = radius * 2 + lineWidth * 2; var ratio = options.ratio; return Stage.canvas(function(ctx) { this.size(width, height, ratio); ctx.scale(ratio, ratio); ctx.beginPath(); ctx.arc(width / 2, height / 2, radius, 0, 2 * Math.PI); if (fillColor) { ctx.fillStyle = fillColor; ctx.fill(); } if (lineColor) { ctx.moveTo(radius + lineWidth, radius + lineWidth); ctx.lineTo(lineWidth, radius + lineWidth); ctx.lineWidth = lineWidth; ctx.strokeStyle = lineColor; ctx.stroke(); } }); }; Viewer.prototype.drawParticle = function(options) { options = this.options.extend(options); var lineWidth = options.get('lineWidth'); var lineColor = ''; var fillColor = options.get('fillColor') || options.get('lineColor'); var radius = 2 * options.get('lineWidth'); var width = radius * 2 + lineWidth * 2; var height = radius * 2 + lineWidth * 2; var ratio = options.ratio; return Stage.canvas(function(ctx) { this.size(width, height, ratio); ctx.scale(ratio, ratio); ctx.beginPath(); ctx.arc(width / 2, height / 2, radius, 0, 2 * Math.PI); if (fillColor) { ctx.fillStyle = fillColor; ctx.fill(); } if (lineColor) { ctx.moveTo(radius + lineWidth, radius + lineWidth); ctx.lineTo(lineWidth, radius + lineWidth); ctx.lineWidth = lineWidth; ctx.strokeStyle = lineColor; ctx.stroke(); } }); }; Viewer.prototype.drawCapsule = function(len, radius, options) { options = this.options.extend(options); var lineWidth = options.get('lineWidth'); var lineColor = options.get('lineColor'); var fillColor = options.get('fillColor'); var width = len + 2 * radius + 2 * lineWidth; var height = 2 * radius + 2 * lineWidth; var ratio = options.ratio; return Stage.canvas(function(ctx) { this.size(width, height, ratio); ctx.scale(ratio, ratio); ctx.beginPath(); ctx.moveTo(radius + lineWidth, lineWidth); ctx.lineTo(len + radius + lineWidth, lineWidth); ctx.arc(len + radius + lineWidth, radius + lineWidth, radius, -Math.PI / 2, Math.PI / 2); ctx.lineTo(radius + lineWidth, 2 * radius + lineWidth); ctx.arc(radius + lineWidth, radius + lineWidth, radius, Math.PI / 2, -Math.PI / 2); ctx.closePath(); if (fillColor) { ctx.fillStyle = fillColor; ctx.fill(); } ctx.lineWidth = lineWidth; ctx.strokeStyle = lineColor; ctx.stroke(); }); }; Viewer.prototype.drawSpring = function(length, options) { options = this.options.extend(options); var lineWidth = options.get('lineWidth'); var lineColor = options.get('lineColor'); var fillColor = options.get('fillColor'); length = Math.max(length, lineWidth * 10); var N = 12; var dx = length / N; var dy = 0.2 * length; var ratio = options.ratio; return Stage.canvas(function(ctx) { this.size(length, dy * 2, ratio); ctx.scale(ratio, ratio); ctx.lineWidth = lineWidth; ctx.strokeStyle = lineColor; ctx.lineJoin = "round"; ctx.moveTo(0, dy); for (var i = 1; i < N; i++) { var x = dx * i; var y = dy; if (i <= 1 || i >= N - 1) { // Do nothing } else if (i % 2 === 0) { y -= dy / 2; } else { y += dy / 2; } ctx.lineTo(x, y); } ctx.lineTo(length, dy); ctx.stroke(); }); }; Viewer.prototype.drawPlane = function(x0, x1, max, options) { options = this.options.extend(options); var lineWidth = options.get('lineWidth'); var lineColor = options.get('lineColor'); var fillColor = options.get('fillColor'); var ratio = options.ratio; return Stage.canvas(function(ctx) { this.size(max * 2, max * 2, ratio); ctx.scale(ratio, ratio); if (fillColor) { ctx.beginPath(); ctx.rect(0, max, 2 * max, 2 * max); ctx.fillStyle = fillColor; ctx.fill(); ctx.closePath(); } ctx.beginPath(); ctx.moveTo(0, max); ctx.lineTo(2 * max, max); ctx.lineWidth = lineWidth; ctx.lineCap = "round"; ctx.strokeStyle = lineColor; ctx.setLineDash && ctx.setLineDash([ 0.12, 0.06 ]); ctx.mozDash = [ 0.12, 0.06 ]; ctx.stroke(); }); }; Viewer.prototype.drawConvex = function(verts, options) { options = this.options.extend(options); var lineWidth = options.get('lineWidth'); var lineColor = options.get('lineColor'); var fillColor = options.get('fillColor'); if (!verts.length) { return; } var width = 0, height = 0; var ratio = options.ratio; for (var i = 0; i < verts.length; i++) { var v = verts[i], x = v[0], y = -v[1]; width = Math.max(Math.abs(x), width); height = Math.max(Math.abs(y), height); } return Stage.canvas(function(ctx) { this.size(2 * width + 2 * lineWidth, 2 * height + 2 * lineWidth, ratio); ctx.scale(ratio, ratio); ctx.beginPath(); for (var i = 0; i < verts.length; i++) { var v = verts[i], x = v[0] + width + lineWidth, y = -v[1] + height + lineWidth; if (i == 0) ctx.moveTo(x, y); else ctx.lineTo(x, y); } if (verts.length > 2) { ctx.closePath(); } if (fillColor) { ctx.fillStyle = fillColor; ctx.fill(); ctx.closePath(); } ctx.lineWidth = lineWidth; ctx.lineCap = "round"; ctx.strokeStyle = lineColor; ctx.stroke(); }); }; })();