241 lines
6.9 KiB
JavaScript
241 lines
6.9 KiB
JavaScript
// import box 2D Lite Javascript module
|
|
import * as box2D from "https://codepen.io/ge1doot/pen/OJXXGKv.js";
|
|
const bodies = box2D.bodies;
|
|
let numBodies = 0;
|
|
let tempo = 0;
|
|
// ---- init canvas ----
|
|
|
|
const canvas = {
|
|
elem: document.createElement("canvas"),
|
|
init(w, h) {
|
|
const ctx = this.elem.getContext("2d");
|
|
this.width = w;
|
|
this.height = h;
|
|
this.elem.width = w;
|
|
this.elem.height = h;
|
|
document.body.appendChild(this.elem);
|
|
this.resize();
|
|
window.addEventListener("resize", () => this.resize(), false);
|
|
return ctx;
|
|
},
|
|
resize() {
|
|
let o = this.elem;
|
|
this.sx = this.width / this.elem.offsetWidth;
|
|
this.sy = this.height / this.elem.offsetHeight;
|
|
for (this.left = 0, this.top = 0; o != null; o = o.offsetParent) {
|
|
this.left += o.offsetLeft;
|
|
this.top += o.offsetTop;
|
|
}
|
|
}
|
|
};
|
|
|
|
// ---- init pointer ----
|
|
|
|
const pointer = {
|
|
x: 0,
|
|
y: 0,
|
|
init() {
|
|
window.addEventListener("mousemove", (e) => this.move(e), false);
|
|
canvas.elem.addEventListener("touchmove", (e) => this.move(e), false);
|
|
window.addEventListener("mousedown", (e) => this.down(e), false);
|
|
window.addEventListener("touchstart", (e) => this.down(e), false);
|
|
},
|
|
move(e) {
|
|
let touchMode = e.targetTouches,
|
|
pointer;
|
|
if (touchMode) {
|
|
e.preventDefault();
|
|
pointer = touchMode[0];
|
|
} else pointer = e;
|
|
this.x = (-canvas.left + pointer.clientX) * canvas.sx;
|
|
this.y = (-canvas.top + pointer.clientY) * canvas.sy;
|
|
},
|
|
down(e) {
|
|
this.move(e);
|
|
e.preventDefault();
|
|
const over = box2D.isPointerInside(ctx, this.x, this.y);
|
|
if (over !== false && over.invMass > 0) {
|
|
if (over.group !== "") {
|
|
const group = over.group;
|
|
for (const body of bodies) {
|
|
if (body.group === group) {
|
|
body.velocity.x = Math.random() * 500 - 250;
|
|
body.velocity.y = -Math.random() * 400;
|
|
if (body.gravity < 0) body.gravity = 40;
|
|
box2D.remove.joints(body);
|
|
body.group = "";
|
|
body.fillColor = "#bbb";
|
|
body.age = 0;
|
|
}
|
|
}
|
|
numBodies--;
|
|
tempo = 0;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// ---- main loop ----
|
|
let frame = 0;
|
|
const run = () => {
|
|
requestAnimationFrame(run);
|
|
ctx.fillStyle = "#eee";
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
box2D.step();
|
|
|
|
for (const body of bodies) {
|
|
body.drawLines(ctx);
|
|
ctx.strokeStyle = "#555";
|
|
ctx.fillStyle = body.fillColor;
|
|
ctx.fill();
|
|
ctx.stroke();
|
|
}
|
|
|
|
let ok = true;
|
|
for (const body of bodies) {
|
|
if (body.invMass > 0.0 && body.group === "" && tempo > 100 && ok === true) {
|
|
ok = false;
|
|
box2D.remove.body(body);
|
|
}
|
|
}
|
|
|
|
if (frame % 140 === 0) {
|
|
if (numBodies < 10) {
|
|
ragdoll(
|
|
100 + Math.floor(Math.random() * 600),
|
|
-1000,
|
|
Math.floor(Math.random() * 360)
|
|
);
|
|
}
|
|
}
|
|
frame++;
|
|
tempo++;
|
|
};
|
|
|
|
// ---- setup ----
|
|
|
|
const ctx = canvas.init(800, 800);
|
|
pointer.init();
|
|
const assets = "https://assets.codepen.io/222599/";
|
|
console.clear();
|
|
|
|
box2D.set.gravity(40);
|
|
box2D.set.iterations(40);
|
|
box2D.set.friction(2.0);
|
|
box2D.set.timeStep(1 / 20);
|
|
box2D.set.allowedPenetration(10.0);
|
|
|
|
box2D.clear();
|
|
|
|
// ground
|
|
let ground = box2D.addBody(400, 850, 800, 100, Infinity);
|
|
|
|
// side walls
|
|
box2D.addBody(-50, 400, 100, 800, Infinity, { friction: 0.0 });
|
|
box2D.addBody(850, 400, 100, 800, Infinity, { friction: 0.0 });
|
|
|
|
// ragdoll
|
|
|
|
const ragdoll = (x, y, hue) => {
|
|
const lum = Math.floor(Math.random() * 40);
|
|
const col1 = `hsl(${hue},50%, ${20 + lum}%`;
|
|
const col2 = `hsl(${hue},50%, ${40 + lum}%`;
|
|
const name = Math.floor(Math.random() * 10000);
|
|
const t1 = box2D.addBody(x, y - 10, 60, 60, -1, {
|
|
group: name,
|
|
fillColor: col1
|
|
});
|
|
const c0 = box2D
|
|
.addBody(x, y + 40, 25, 20, -1, { group: name, fillColor: col2 })
|
|
.addJoint(t1, 0, -10, 0, 35, 0);
|
|
const c1 = box2D
|
|
.addBody(x, y + 55, 100, 10, -1, { group: name, fillColor: col1 })
|
|
.addJoint(c0, 0, -5, 0, 10, 0);
|
|
const b1 = box2D
|
|
.addBody(x, y + 65, 25, 10, -1, { group: name, fillColor: col2 })
|
|
.addJoint(c1, 0, -5, 0, 5, 0);
|
|
const c2 = box2D
|
|
.addBody(x, y + 75, 100, 10, -1, { group: name, fillColor: col1 })
|
|
.addJoint(b1, 0, -5, 0, 5, 0);
|
|
const b2 = box2D
|
|
.addBody(x, y + 85, 25, 10, -1, { group: name, fillColor: col2 })
|
|
.addJoint(c2, 0, -5, 0, 5, 0);
|
|
const c3 = box2D
|
|
.addBody(x, y + 95, 100, 10, -1, { group: name, fillColor: col1 })
|
|
.addJoint(b2, 0, -5, 0, 5, 0);
|
|
const b3 = box2D
|
|
.addBody(x, y + 105, 25, 10, -1, { group: name, fillColor: col2 })
|
|
.addJoint(c3, 0, -5, 0, 5, 0);
|
|
const c4 = box2D
|
|
.addBody(x, y + 115, 100, 10, -1, { group: name, fillColor: col1 })
|
|
.addJoint(b3, 0, -5, 0, 5, 0);
|
|
const b4 = box2D
|
|
.addBody(x, y + 125, 25, 15, -1, { group: name, fillColor: col2 })
|
|
.addJoint(c4, 0, -8.5, 0, 5, 0);
|
|
const b5 = box2D
|
|
.addBody(x, y + 140, 25, 15, -1, { group: name, fillColor: col2 })
|
|
.addJoint(b4, 0, -8.5, 0, 8.5, 0);
|
|
const b6 = box2D
|
|
.addBody(x, y + 155, 25, 15, -1, { group: name, fillColor: col2 })
|
|
.addJoint(b5, 0, -8.5, 0, 8.5, 0);
|
|
const h1 = box2D
|
|
.addBody(x, y + 185, 100, 30, -1, { group: name, fillColor: col1 })
|
|
.addJoint(b6, 0, -15, 0, 7.5, 0);
|
|
const l1 = box2D
|
|
.addBody(x - 25, y + 240, 30, 80, -1, { group: name, fillColor: col2 })
|
|
.addJoint(h1, 0, -40, -25, 15, 0.05);
|
|
const p1 = box2D
|
|
.addBody(x - 25, y + 330, 20, 100, -1, { group: name, fillColor: col2 })
|
|
.addJoint(l1, 0, -52.5, 0, 42.5, 0);
|
|
const p3 = box2D
|
|
.addBody(x - 25, y + 390, 30, 20, -1, { group: name, fillColor: col1 })
|
|
.addJoint(p1, 0, -12.5, 0, 52.5, 0);
|
|
const l2 = box2D
|
|
.addBody(x + 25, y + 240, 30, 80, -1, { group: name, fillColor: col2 })
|
|
.addJoint(h1, 0, -40, 25, 15, 0.05);
|
|
const p2 = box2D
|
|
.addBody(x + 25, y + 330, 20, 100, -1, { group: name, fillColor: col2 })
|
|
.addJoint(l2, 0, -52.5, 0, 42.5, 0);
|
|
const p4 = box2D
|
|
.addBody(x + 25, y + 390, 30, 20, -1, { group: name, fillColor: col1 })
|
|
.addJoint(p2, 0, -12.5, 0, 52.5, 0);
|
|
const e1 = box2D
|
|
.addBody(x - 75, y + 60, 40, 40, -1, { group: name, fillColor: col1 })
|
|
.addJoint(c1, 22.5, 0, -52.5, 0, 0.1);
|
|
const e2 = box2D
|
|
.addBody(x + 75, y + 60, 40, 40, -1, { group: name, fillColor: col1 })
|
|
.addJoint(c1, -22.5, 0, 52.5, 0, 0.1);
|
|
const r1 = box2D
|
|
.addBody(x - 75, y + 115, 20, 60, -1, { group: name, fillColor: col2 })
|
|
.addJoint(e1, 0, -32.5, 0, 22.5, 0);
|
|
const r2 = box2D
|
|
.addBody(x + 75, y + 115, 20, 60, -1, { group: name, fillColor: col2 })
|
|
.addJoint(e2, 0, -32.5, 0, 22.5, 0);
|
|
const a1 = box2D
|
|
.addBody(x - 75, y + 190, 15, 80, -1, { group: name, fillColor: col2 })
|
|
.addJoint(r1, 0, -42.5, 0, 32.5, 0);
|
|
const a2 = box2D
|
|
.addBody(x + 75, y + 190, 15, 80, -1, { group: name, fillColor: col2 })
|
|
.addJoint(r2, 0, -42.5, 0, 32.5, 0);
|
|
const m1 = box2D
|
|
.addBody(x - 75, y + 250, 25, 30, -1, {
|
|
group: name,
|
|
gravity: -150 * Math.random(),
|
|
fillColor: col1
|
|
})
|
|
.addJoint(a1, 0, -17.5, 0, 42.5, 0);
|
|
const m2 = box2D
|
|
.addBody(x + 75, y + 250, 25, 30, -1, {
|
|
group: name,
|
|
gravity: -150 * Math.random(),
|
|
fillColor: col1
|
|
})
|
|
.addJoint(a2, 0, -17.5, 0, 42.5, 0);
|
|
numBodies++;
|
|
};
|
|
|
|
ragdoll(200, 100, Math.floor(Math.random() * 360));
|
|
ragdoll(400, 100, Math.floor(Math.random() * 360));
|
|
ragdoll(600, 100, Math.floor(Math.random() * 360));
|
|
|
|
run(); |