<!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>