codepens/to-stick-and-stand/dist/script.js

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