Scale
Game made during a code-together discussion with students, using the prompt "Heavy" from Inktober 2025, day 9.
Draw two shapes, then guess which one is heavier (that is, has a larger area). Get more point for guessing between shapes that are very close in area.
function setup() {
createCanvas(400, 330)
}
let mode = "shapeL";
let shapeL = [];
let shapeR = [];
let shapeLArea = 0;
let shapeRArea = 0;
let scaleAngle = 0;
let scaleAngleV = 0;
let points = 0;
let t = 0;
let guess = "";
function draw() {
background(220);
textSize(20);
textAlign(CENTER, CENTER);
if (mode == "guess") {
scaleAngleV = (cos(t / 23) / 23) * 0.1;
t += (deltaTime / 1000) * 60;
}
if (mode == "weight" || mode == "finish") {
let areaDiff = shapeRArea - shapeLArea;
scaleAngleV += pow(abs(areaDiff), 1/4) * Math.sign(areaDiff) * 0.00001;
}
scaleAngle += scaleAngleV;
if (abs(scaleAngle) > 0.3) {
scaleAngle = Math.sign(scaleAngle) * 0.3;
scaleAngleV = -scaleAngleV * 0.1;
if (
mode == "weight" &&
Math.sign(scaleAngle) == Math.sign(shapeRArea - shapeLArea) &&
abs(scaleAngleV) < 0.001
) {
mode = "finish";
}
}
if (
mode == "weight" && shapeRArea == shapeLArea &&
abs(scaleAngleV) < 0.001
) {
mode = "finish";
}
push();
translate(200, 200);
rotate(scaleAngle);
drawScaleArm();
push();
scale(-1, 1);
drawScaleArm();
pop();
push();
translate(-95, 0);
rotate(-scaleAngle);
line(-80, 0, 80, 0);
if (mode == "shapeL") {
drawShapeArea("Draw left shape");
}
drawShape(shapeL, mode == "guess" || guess == "L");
pop();
push();
translate(95, 0);
rotate(-scaleAngle);
line(-80, 0, 80, 0);
if (mode == "shapeR") {
drawShapeArea("Draw right shape");
}
drawShape(shapeR, mode == "guess" || guess == "R");
pop();
pop();
if (mode == "guess") {
text("Guess which one is heavier", 200, 280);
}
if (mode == "finish") {
text(
shapeLArea == shapeRArea
? "They are equal! 😮" :
(guess == "L") == (shapeLArea > shapeRArea)
? "Correct! 🎉\n+" + calcPoints()
: "Incorrect! 🫤\n-" + calcPoints(),
200,
280
);
}
if (points != 0) {
textAlign(RIGHT, TOP);
text(points, 390, 10);
}
}
function mousePressed() {
if (mode == "shapeL") {
if (mouseX < 190 && mouseX > 20 && mouseY < 200 && mouseY > 60) {
shapeL.push([mouseX - 200 + 95 + random(-1,1), mouseY - 200 + random(-1,1)]);
} else if (shapeL.length >= 3) {
mode = "shapeR";
}
}
if (mode == "shapeR") {
if (mouseX < 480 && mouseX > 210 && mouseY < 200 && mouseY > 60) {
shapeR.push([mouseX - 200 - 95 + random(-1,1), mouseY - 200 + random(-1,1)]);
} else if (shapeR.length >= 3) {
mode = "guess";
shapeLArea = calcShapeArea(shapeL);
shapeRArea = calcShapeArea(shapeR);
return;
}
}
if (mode == "guess") {
scaleAngleV += random(-0.2, 0.2);
if (mouseX < 190) {
guess = "L";
mode = "weight";
} else if (mouseX > 210) {
guess = "R";
mode = "weight";
}
}
if (mode == "finish") {
points +=
(shapeLArea == shapeRArea ? 0 : (guess == "L") == shapeLArea > shapeRArea ? 1 : -1) * calcPoints();
shapeL = [];
shapeR = [];
mode = "shapeL";
scaleAngle = 0;
scaleAngleV = 0;
guess = "";
t = 0
}
}
function drawScaleArm() {
line(0, 0, 10, 25);
line(95, 0, 85, 25);
line(10, 25, 85, 25);
}
function drawShapeArea(txt) {
text(txt, 0, -150);
push();
stroke("#3E4943");
fill(
lerpColor(
color("#A6E7C4"),
color("#C8ECD7"),
sin(millis() / 300) / 2 + 0.5
)
);
rect(-75, -135, 150, 130);
pop();
}
function drawShape(shapeP, selected) {
if (selected) {
fill(
lerpColor(
color("#F2EAA8"),
color("#F4E4C3"),
sin(millis() / 300) / 2 + 0.5
)
);
}
beginShape();
for (let p of shapeP) {
vertex(...p);
}
endShape(CLOSE);
}
function calcShapeArea(shapeP) {
let area = 0;
for (let i = 0; i < shapeP.length; i++) {
let p_i = shapeP[i];
let p_i1 = shapeP[(i + 1) % shapeP.length];
area += (p_i[0] + p_i1[0]) * (p_i[1] - p_i1[1]);
}
return abs(area / 2);
}
function calcPoints() {
return round(1000 / (abs(shapeLArea - shapeRArea) + 10));
}(Originally seen at https://editor.p5js.org/bojidar-bg/sketches/eEfTsJloa)
Browse more articles?
← Noise visualizer Experiments tagged p5 (63/85) Block-packing game →
← Match sets Experiments tagged game (7/11) Block-packing game →
← Noise visualizer Experiments on this site (63/85) Block-packing game →