//Bug fixes and optimisation // https://www.py4u.net/discuss/335084 //feature to add https://b-g.github.io/p5-matter-examples/12-attractor/ //sketch for HOME PAGE //detectmobile device var detector = new MobileDetect(window.navigator.userAgent); var mobile=false; //matterjs setup Matter.use('matter-attractors'); const Engine = Matter.Engine; const World = Matter.World; const Bodies = Matter.Bodies; const Body = Matter.Body; const Events = Matter.Events; const Composite = Matter.Composite; const Mouse = Matter.Mouse; const MouseConstraint = Matter.MouseConstraint; const Constraint = Matter.Constraint; const Runner = Matter.Runner; const Composites = Matter.Composites; const drawBodies = Helpers.drawBodies; const drawBody = Helpers.drawBody; const drawMouse = Helpers.drawMouse; const drawSprites = Helpers.drawSprites; var dragBody = null; let attractor; let boxes; var runner = Runner.create({ isFixed: false, //simulation refreshrate //delta: 1000 / 240 }); //// engine is the simulation let engine, world, mconst, mousebox, mouse; let bounds; let mX, mY; let cursorimg,usercursorimg; var colors = ["#FFC47F","#C3A0FF","#FFBBAD","#F5B6ED","#F0FFAE"], currentcolor=2; var wallcollider = 0x0001, mousecollider = 0x0002, othercollider = 0x0004; //objects //width and height let w1, h1; function setup() { //setting canvas size const canvas = createCanvas(windowWidth, windowHeight); canvas.position(0, 0); canvas.id('sketch'); w1 = windowWidth; h1 = windowHeight; // frameRate(120); // create an engine engine = Engine.create(); world = engine.world; currentcolor=Math.floor(Math.random() * colors.length); cursorimg = loadImage('https://uploads-ssl.webflow.com/61729645471a28201eae8786/6188cd35ccf1bc163e40b1e0_cursor.png'); //usercursorimg = loadImage('cursor_main.png'); pixelDensity(2); // Populate objects and start simulation enginesetup(); } function mobilechecker(){ if( navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/Windows Phone/i)) mobile=true; } function windowResized() { //redraw the canvas; if(!mobile){ resizeCanvas(windowWidth, windowHeight); w1 = windowWidth; h1 = windowHeight; currentcolor=Math.floor(Math.random() * colors.length); //reset engine enginesetup(); pixelDensity(2); } } function draw() { background(255); fill(0); noStroke(); //updatemouse(); //fill(255,0,0); fill(colors[currentcolor]); //physics from matterjs drawBody(bounds); //vertex drawing of bounds in p5 beginShape(); for (var j = 0; j < 8; j++) vertex(bounds.vertices[j].x, bounds.vertices[j].y); endShape(CLOSE); fill(255, 255); drawSprites(boxes.bodies,cursorimg); // drawBodies(boxes.bodies); updatemouse(); drawBody(attractor); //drawSprite(attractor,usercursorimg), } //console.log(mousebox); function mousePressed() { currentcolor=Math.floor(Math.random() * colors.length); } function enginesetup() { //resets the world and engine World.clear(world); Engine.clear(engine); //adds the bodies setbodies(); //runs the engine engine.world.gravity.scale = 0; Runner.run(runner, engine); } //adds bodies to the world function setbodies() { //objects //bounds bottom = Bodies.rectangle(w1 / 2, h1, w1, 2, { isStatic: true }); left = Bodies.rectangle(2, h1 / 2, 2, h1, { isStatic: true }); right = Bodies.rectangle(w1 - 2, h1 / 2, 2, h1, { isStatic: true }); roof = Bodies.rectangle(w1 / 2, 0, w1, 2, { isStatic: true }); //make a compound object parts = []; pad=0.04*w1; parts.push( Bodies.rectangle(w1 / 2, h1 -pad, w1 -pad*2, 1, { isStatic: false }), Bodies.rectangle(pad, h1 / 2, 1, h1 -pad*2, { isStatic: false }), Bodies.rectangle(w1 - pad, h1 / 2, 1, h1-pad*2, { isStatic: false }), Bodies.rectangle(w1 / 2, pad, w1 -pad*2, 1, { isStatic: false }) ); //1000001 is a hack to not attract bounds = Body.create({ parts,frictionAir: 0.02, friction : 0.1, mass: 300, inertia: 100000, isStatic: false, collisionFilter: { category: wallcollider } }); //boundsconstraints boundsconst1= Constraint.create({ bodyA: bounds, pointB: { x: w1/2, y: h1/2 }, length: 0, stiffness:0.0001, damping:0.005 }); World.add(world, [bounds,boundsconst1]); World.add(world, [bottom, left, right, roof]); //mouse mouse = Mouse.create(canvas.elt); var options = { mouse: mouse, constraint: { stiffness: 0.002, damping: 0.1 } }; //mconst = MouseConstraint.create(engine, options); mX = 100; mY = 100; // World.add(world, [mconst]); attractor = Bodies.circle(400, 400, 50, { isStatic: false, mass:90, friction: 0.2, collisionFilter: { category: mousecollider, mask: mousecollider | othercollider }, plugin: { attractors: [ function (bodyA, bodyB) { var force = { x: (bodyA.position.x - bodyB.position.x) * 1.5e-7 + random(-5,5) * 1.8e-4, y: (bodyA.position.y - bodyB.position.y) * 1.5e-7 + + random(-5,5) * 1.8e-4, }; // apply force to both bodies Body.applyForce(bodyA, bodyA.position, Matter.Vector.neg(force)); Body.applyForce(bodyB, bodyB.position, force); } ] } }); World.add(engine.world, attractor); // add boxes // xx, yy, columns, rows, columnGap, rowGap if(mobile) cursornumber =10; else cursornumber=12; boxes = Composites.stack(width / 4, height/8, cursornumber, cursornumber, width/100,height/100, function (x, y) { var rand=random(0.6,2); return Bodies.rectangle(x, y, 15, 25, {mass:0.5,restitution:0.1, frictionAir:0.01, friction:0.2, collisionFilter: { category: othercollider }}); }); World.add(engine.world, boxes); } function updatemouse() { // smoothly move the attractor body towards the mouse Body.translate(attractor, { x: (mouseX - attractor.position.x) * 0.15, y: (mouseY - attractor.position.y) * 0.15 }); } //optimisation Matter.Events.on(engine, "beforeUpdate", function (event) { counter += 0.014; if (counter < 0) { return; } var px = 400 + 100 * Math.sin(counter); Matter.Body.setVelocity(body, { x: px - body.position.x, y: 0 }); Matter.Body.setPosition(body, { x: px, y: body.position.y }); if (dragBody != null) { if (dragBody.velocity.x > 12.0) { Matter.Body.setVelocity(dragBody, { x: 12, y: dragBody.velocity.y }); } if (dragBody.velocity.y > 12.0) { Matter.Body.setVelocity(dragBody, { x: dragBody.velocity.x, y: 12 }); } if (dragBody.positionImpulse.x > 12.0) { dragBody.positionImpulse.x = 12.0; } if (dragBody.positionImpulse.y > 12.0) { dragBody.positionImpulse.y = 12.0; } } }); Matter.Events.on(mouseConstraint, "startdrag", function (event) { dragBody = event.body; });