%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();
});
};
})();