Concept & Inspiration
In this project, I aimed to combine p5.js with the physics simulation capabilities of Matter.js to create an interactive system where bouncing stars move within the canvas, reacting to boundaries. I wanted to explore how these two libraries could be integrated for simple but engaging visual experiences. The stars, initially inspired by the random and organic movements of celestial bodies, move around the canvas with random velocities, reacting to invisible boundaries.
My main focus was on creating something visually appealing while incorporating realistic physical dynamics. The stars move around, bounce off the walls, and continuously change their positions within the boundaries of the canvas. This combination of physics and aesthetics makes the piece both dynamic and fun to interact with.
Features
- Random Star Motion: The stars start with random velocities, making their motion unpredictable and engaging.
- Boundaries: Stars bounce off invisible walls placed around the canvas, ensuring that they stay within the visible area.
- Dynamic Shapes: Each star is drawn in the shape of a star polygon, and its size is randomized for variety.
- Physics with Matter.js: The use of Matter.js allows for a realistic simulation of bouncing behavior, including restitution (bounciness) and air resistance.
How It Works
The project uses Matter.js to handle physics simulation and p5.js for rendering and interaction. The following steps were followed to create this effect:
- Physics Engine Setup: A Matter.js engine is created, and four boundary walls are added to the world to act as the invisible edges of the canvas.
- Star Creation: 10 stars are generated with random sizes and positions on the canvas. They are assigned random velocities at the start, so they move in random directions.
- Bounce Behavior: Each star is a circle in the physics world, and the
restitution
property gives them a bouncy behavior when they collide with walls or each other. - Custom Drawing: While the physics simulation treats them as circles, each star is visually represented by a custom star shape using p5.js.
Code
// Matter.js module aliases let Engine = Matter.Engine, Render = Matter.Render, Runner = Matter.Runner, Bodies = Matter.Bodies, Composite = Matter.Composite, World = Matter.World, Body = Matter.Body; // To manipulate bodies // Variables for engine and world let engine, world; let stars = []; let walls = []; function setup() { createCanvas(800, 600); // Create Matter.js engine and world engine = Engine.create(); world = engine.world; // Disable gravity (or you can set a lower value to simulate reduced gravity) engine.gravity.y = 0.0; // Create canvas boundaries (walls) let thickness = 50; let wallTop = Bodies.rectangle(width / 2, -thickness / 2, width, thickness, { isStatic: true }); let wallBottom = Bodies.rectangle(width / 2, height + thickness / 2, width, thickness, { isStatic: true }); let wallLeft = Bodies.rectangle(-thickness / 2, height / 2, thickness, height, { isStatic: true }); let wallRight = Bodies.rectangle(width + thickness / 2, height / 2, thickness, height, { isStatic: true }); // Add walls to the world World.add(world, [wallTop, wallBottom, wallLeft, wallRight]); // Create stars with random velocities for (let i = 0; i < 10; i++) { let x = random(100, width - 100); let y = random(100, height - 100); let star = Bodies.circle(x, y, random(20, 40), { restitution: 0.8, // Make the stars bouncy frictionAir: 0.01 // Add some air resistance to make them slow down }); stars.push(star); World.add(world, star); // Apply random initial velocity to each star Body.setVelocity(star, { x: random(-3, 3), // Random velocity on X axis y: random(-3, 3) // Random velocity on Y axis }); } } function draw() { background(0); // Update the Matter.js engine Engine.update(engine); // Display the stars fill(255, 204, 0); for (let star of stars) { drawStar(star.position.x, star.position.y, star.circleRadius); } } function drawStar(x, y, radius) { push(); translate(x, y); beginShape(); let angle = TWO_PI / 5; let halfAngle = angle / 2.0; for (let a = 0; a < TWO_PI; a += angle) { let sx = cos(a) * radius; let sy = sin(a) * radius; vertex(sx, sy); sx = cos(a + halfAngle) * (radius / 2); sy = sin(a + halfAngle) * (radius / 2); vertex(sx, sy); } endShape(CLOSE); pop(); }
Reflection and Future Work
This project demonstrates a basic integration of p5.js and Matter.js, with the stars floating and bouncing within the defined space. Although the interaction is basic, it opens up various possibilities for future improvements:
- Interactivity: Adding mouse or keyboard interaction could allow users to influence the stars’ motion or add new stars dynamically.
- Forces: Introducing different types of forces like gravity or wind could add more complexity to the motion.
- Collisions: Currently, stars only collide with the walls, but enabling star-star collision effects could add more dynamics to the system.