xxxxxxxxxx
222
p5.disableFriendlyErrors = true //Speed Trick. REF: https://p5js.org/tutorials/how-to-optimize-your-sketches/
let containerDiv = document.getElementById('sketch-holder')
let positionInfo = containerDiv.getBoundingClientRect()
let divHeight = positionInfo.height
let divWidth = positionInfo.width
containerDiv.style.height = `${window.innerHeight}px`
let img
let sound
let particles = []
let comPosition = { x: 0, y: 0 } // Center of Mass position
const COLS = 30 // Number of columns
const ROWS = 20 // Number of rows
let pieceWidth, pieceHeight
let engine, world
let trajectory = []
let goBanged = false
function preload () {
sound = loadSound('cracker_sound.mp3')
img = loadImage('cracker.png')
}
function setup () {
let cnv = createCanvas(window.innerWidth*0.9, window.innerHeight * 0.95)
cnv.style('display', 'flex')
cnv.style('border-radius', '20px')
cnv.parent('sketch-holder')
// Set up the Matter.js engine and world
engine = Matter.Engine.create()
world = engine.world
// Gravity settings
engine.world.gravity.x = 0.018
engine.world.gravity.y = 0.09
pieceWidth = img.width / COLS
pieceHeight = img.height / ROWS
Matter.Runner.run(engine)
init()
}
function init() {
particles = []
comPosition = { x: 0, y: 0 }
trajectory = []
goBanged = false
// Create particles for each image piece
for (let i = 0; i < COLS; i++) {
for (let j = 0; j < ROWS; j++) {
let x = i * pieceWidth + pieceWidth / 2 - 20
let y = j * pieceHeight + pieceHeight / 2 + height - 100
let p = new Particle(x, y, pieceWidth, pieceHeight, i, j)
particles.push(p)
}
}
}
function draw () {
background('#111')
//image(0, 0, imgStick1);
// Show each particle (image piece)
for (let particle of particles) {
particle.show(goBanged)
}
if (!goBanged) {
imageMode(CENTER)
image(img, comPosition.x, comPosition.y)
}
// Calculate Center of Mass
calculateCenterOfMass()
trajectory.push({ x: comPosition.x - 28, y: comPosition.y + 17 })
strokeWeight(1)
for (let i = 0; i < trajectory.length - 1; i++) {
stroke('#EBF4FA ')
line(
trajectory[i].x,
trajectory[i].y,
trajectory[i + 1].x,
trajectory[i + 1].y
)
}
// Draw the Center of Mass
let sine = abs(sin(0.2 * frameCount))
noStroke()
fill(50, 100 + sine * 155, 100 + sine * 155) // Red color for the COM
ellipse(comPosition.x - 28, comPosition.y + 17, 1 + sine * 10)
fill(0,255,255,50)
ellipse(comPosition.x - 28,comPosition.y + 17, 30, 30)
}
function explodeCracker () {
let array_size = particles.length - 1
if (!sound.isPlaying()) {
sound.play()
}
for (let i = array_size; i > -1; i--) {
for (let j = i - 1; j > -1; j--) {
let force_x = random(-0.0000001, 0.00009)
let force_y = random(-0.0000001, 0.00009)
let force_plus = Matter.Vector.create(force_x, force_y)
let force_minus = Matter.Vector.create(-force_x, -force_y)
Matter.Body.applyForce(
particles[i].body,
particles[i].body.position,
force_plus
)
Matter.Body.applyForce(
particles[j].body,
particles[j].body.position,
force_minus
)
}
}
}
function calculateCenterOfMass () {
let totalMass = 0
let comX = 0
let comY = 0
for (let p of particles) {
totalMass += p.mass
comX += p.x * p.mass
comY += p.y * p.mass
}
if (totalMass > 0) {
comPosition.x = comX / totalMass
comPosition.y = comY / totalMass
}
}
// Particle class using Matter.js physics
class Particle {
constructor (x, y, w, h, col, row) {
this.w = w
this.h = h
this.col = col
this.row = row
this.x = x
this.y = y
// Create a physical body for the particle
this.body = Matter.Bodies.rectangle(
x,
y,
w,
h,
{
mass: random(0.001, 0.1)
},
{
restitution: 1.0
}
)
this.mass = this.body.mass
this.body.angle = 0.0
//Matter.Body.setAngularVelocity(this.body, 0.05);
Matter.Body.setVelocity(this.body, { x: 1.45, y: -10 })
Matter.World.add(world, this.body)
}
explode () {
// Apply a random burst force in a random direction
let force = Matter.Vector.create(
random(-0.0025, 0.0025),
random(-0.0025, 0.0025)
)
Matter.Body.applyForce(this.body, this.body.position, force)
}
show (showImage = true) {
// Get the position and angle from Matter.js physics engine
let pos = this.body.position
let angle = this.body.angle
this.x = pos.x
this.y = pos.y
if (showImage) {
push()
translate(pos.x, pos.y)
rotate(angle)
// Draw the image piece based on the particle's position and angle
let sx = this.col * this.w
let sy = this.row * this.h
imageMode(CENTER)
image(img, 0, 0, this.w, this.h, sx, sy, this.w, this.h)
pop()
}
}
}
let btnGoBang = document.getElementById('gobang')
let btnRelaunch = document.getElementById('relaunch')
btnGoBang.addEventListener('click', e => {
if (!goBanged) {
e.preventDefault()
explodeCracker()
goBanged = true
}
})
btnRelaunch.addEventListener('click', e => {
if (goBanged) {
e.preventDefault()
init()
}
})