<!DOCTYPE html> <html> <head> <title>Angry Birds Clone</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js"></script> <style> body { margin: 0; } canvas { display: block; } </style> </head> <body> <script> // Module aliases const { Engine, Render, Runner, Bodies, Mouse, MouseConstraint, World, Constraint, Vector } = Matter; // Create an engine const engine = Engine.create(); const world = engine.world; // Create a renderer const render = Render.create({ element: document.body, engine: engine, options: { width: 800, height: 600, wireframes: false, background: '#87CEEB' } }); // Create ground const ground = Bodies.rectangle(400, 590, 810, 60, { isStatic: true }); World.add(world, ground); // Create bird const bird = Bodies.circle(150, 300, 20, { density: 0.004 }); World.add(world, bird); // Create slingshot let slingshot = Constraint.create({ pointA: { x: 150, y: 300 }, bodyB: bird, stiffness: 0.05, length: 0 }); World.add(world, slingshot); // Create targets (blocks) const createBlock = (x, y) => { return Bodies.rectangle(x, y, 40, 40, { restitution: 0.8, friction: 0.5 }); }; const blocks = [ createBlock(600, 550), createBlock(650, 550), createBlock(700, 550), createBlock(625, 500), createBlock(675, 500), createBlock(650, 450) ]; World.add(world, blocks); // Add mouse control const mouse = Mouse.create(render.canvas); const mouseConstraint = MouseConstraint.create(engine, { mouse: mouse, constraint: { stiffness: 0.2, render: { visible: false } } }); World.add(world, mouseConstraint); // Variables to track bird's position and slingshot release let isBirdReleased = false; let birdStartPosition = { x: 150, y: 300 }; // Event to handle end drag Matter.Events.on(mouseConstraint, 'enddrag', (event) => { if (event.body === bird) { slingshot.bodyB = null; isBirdReleased = true; } }); // Reset bird position const resetBird = () => { Matter.Body.setPosition(bird, birdStartPosition); Matter.Body.setVelocity(bird, { x: 0, y: 0 }); Matter.Body.setAngularVelocity(bird, 0); slingshot.bodyB = bird; isBirdReleased = false; }; // Apply force to the bird when it is released Matter.Events.on(engine, 'afterUpdate', () => { if (isBirdReleased) { const forceMagnitude = 0.02 * bird.mass; const slingshotVector = Vector.sub(slingshot.pointA, bird.position); const normalizedVector = Vector.normalise(slingshotVector); const force = Vector.mult(normalizedVector, forceMagnitude); Matter.Body.applyForce(bird, bird.position, force); isBirdReleased = false; // Ensure force is applied only once } // Check if bird is out of bounds if (bird.position.x > 800 || bird.position.y > 600 || bird.position.x < 0 || bird.position.y < 0) { resetBird(); } }); // Run the engine and renderer Engine.run(engine); Render.run(render); </script> </body> </html>