drawCube(x, y, col, angle)
drawCube demonstrates isometric projection—a technique for drawing 3D shapes on a 2D canvas by using specific coordinate relationships. Each face is a quad() with hardcoded isometric offsets (e.g., y - 15 for the top-right corner). The function also applies rotation from Matter.js and camera translation, showing how to compose multiple transforms without interfering with other objects.
🔬 This function draws three faces. What happens if you comment out the left face quad() call? How does removing that face change what you see?
// Top Face
fill(col);
quad(x, y, x + 30, y - 15, x + 60, y, x + 30, y + 15);
// Left Face
fill(lerpColor(col, color(0), 0.2));
quad(x, y, x + 30, y + 15, x + 30, y + 45, x, y + 30);
🔬 These nested translates and rotate create the rotation magic. What if you changed the second translate to translate(x + 50, y + 30) instead? Where would the pivot point move?
translate(0, camY); // Translate everything based on camera
// Translate to the center of the physics body, then rotate
// Matter.js bodies are centered, so we adjust p5's drawing origin
// to the center of our isometric block's base for rotation.
// The isometric block's base center is at (x + 30, y + 15).
translate(x + 30, y + 15);
rotate(angle);
translate(-(x + 30), -(y + 15));
var drawCube = function(x, y, col, angle) {
push();
translate(0, camY); // Translate everything based on camera
// Translate to the center of the physics body, then rotate
// Matter.js bodies are centered, so we adjust p5's drawing origin
// to the center of our isometric block's base for rotation.
// The isometric block's base center is at (x + 30, y + 15).
translate(x + 30, y + 15);
rotate(angle);
translate(-(x + 30), -(y + 15)); // Translate back for actual cube drawing
// Top Face
fill(col);
quad(x, y, x + 30, y - 15, x + 60, y, x + 30, y + 15);
// Left Face
fill(lerpColor(col, color(0), 0.2));
quad(x, y, x + 30, y + 15, x + 30, y + 45, x, y + 30);
// Right Face
fill(lerpColor(col, color(0), 0.4));
quad(x + 30, y + 15, x + 60, y, x + 60, y + 30, x + 30, y + 45);
pop();
};
Line-by-line explanation (13 lines)
🔧 Subcomponents:
translate(0, camY);
Shifts all drawing upward by camY pixels, creating the illusion that the camera is following the tower
translate(x + 30, y + 15);
rotate(angle);
translate(-(x + 30), -(y + 15));
Rotates the block around its center point (x+30, y+15) based on its physics body's angle
quad(x, y, x + 30, y - 15, x + 60, y, x + 30, y + 15);
Draws the top-facing surface of the cube using isometric coordinates (the brightest face)
quad(x, y, x + 30, y + 15, x + 30, y + 45, x, y + 30);
Draws the left side of the cube, darkened by 20% to create depth
quad(x + 30, y + 15, x + 60, y, x + 60, y + 30, x + 30, y + 45);
Draws the right side of the cube, darkened by 40% to create strong shadow
var drawCube = function(x, y, col, angle) {- Defines a function that takes the block's isometric x and y position, its color, and its rotation angle from Matter.js
push();- Saves the current transformation matrix so camera and rotation only affect this cube
translate(0, camY);- Moves everything down by camY pixels, which shifts the entire canvas view upward as the tower grows
translate(x + 30, y + 15);- Moves the origin to the center of the cube (offset from its top-left corner)
rotate(angle);- Rotates the cube around its center by the angle provided by the Matter.js physics body
translate(-(x + 30), -(y + 15));- Moves the origin back so the cube draws at its original position, but now rotation is applied
fill(col);- Sets the fill color to the cube's assigned color for the top face
quad(x, y, x + 30, y - 15, x + 60, y, x + 30, y + 15);- Draws the top face using four isometric points that create a diamond shape
fill(lerpColor(col, color(0), 0.2));- Blends the cube's color 20% toward black, darkening the left face for depth
quad(x, y, x + 30, y + 15, x + 30, y + 45, x, y + 30);- Draws the left face of the isometric cube
fill(lerpColor(col, color(0), 0.4));- Blends the cube's color 40% toward black, creating even darker shadow on the right
quad(x + 30, y + 15, x + 60, y, x + 60, y + 30, x + 30, y + 45);- Draws the right face of the isometric cube
pop();- Restores the transformation matrix so the next cube is not affected by this one's rotation and translation