knockback-game/
├── index.html
├── css/
│ └── style.css
├── js/
│ └── game.js
└── README.md
Here are the file contents:
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Knockback Punching Game</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="score">Score: 0</div>
<div id="controls">
<p>Click to punch | Space to reset</p>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
<script src="js/game.js"></script>
</body>
</html>
css/style.css:
body {
margin: 0;
padding: 0;
overflow: hidden;
background: #f0f0f0;
font-family: Arial, sans-serif;
}
canvas {
display: block;
background: #222;
}
#score {
position: absolute;
top: 10px;
left: 10px;
color: white;
font-size: 24px;
}
#controls {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
color: white;
text-align: center;
}
js/game.js:
// Setup Matter.js
const Engine = Matter.Engine,
Render = Matter.Render,
World = Matter.World,
Bodies = Matter.Bodies,
Body = Matter.Body,
Events = Matter.Events;
// Create engine
const engine = Engine.create({
gravity: { x: 0, y: 1 }
});
const world = engine.world;
// Create renderer
const render = Render.create({
element: document.body,
engine: engine,
options: {
width: window.innerWidth,
height: window.innerHeight,
wireframes: false,
background: '#222'
}
});
// Game variables
let score = 0;
const scoreElement = document.getElementById('score');
const blocks = [];
const blockSize = 50;
const colors = ['#FF5252', '#FF4081', '#E040FB', '#7C4DFF', '#536DFE', '#448AFF', '#40C4FF', '#18FFFF', '#64FFDA', '#69F0AE'];
// Create ground
const ground = Bodies.rectangle(
window.innerWidth / 2,
window.innerHeight - 20,
window.innerWidth,
40,
{ isStatic: true, friction: 0.3, restitution: 0.6 }
);
// Create walls
const leftWall = Bodies.rectangle(
0,
window.innerHeight / 2,
40,
window.innerHeight,
{ isStatic: true }
);
const rightWall = Bodies.rectangle(
window.innerWidth,
window.innerHeight / 2,
40,
window.innerHeight,
{ isStatic: true }
);
// Add all to world
World.add(world, [ground, leftWall, rightWall]);
// Create blocks
function createBlock() {
const x = Math.random() * (window.innerWidth - blockSize * 2) + blockSize;
const y = 100;
const color = colors[Math.floor(Math.random() * colors.length)];
const block = Bodies.rectangle(x, y, blockSize, blockSize, {
restitution: 0.6,
friction: 0.1,
render: {
fillStyle: color
}
});
blocks.push(block);
World.add(world, block);
}
// Punch function
function punch(x, y) {
const punchForce = 0.05;
const punchRadius = 200;
blocks.forEach(block => {
const distance = Math.sqrt(
Math.pow(block.position.x - x, 2) +
Math.pow(block.position.y - y, 2)
);
if (distance < punchRadius) {
const force = {
x: (block.position.x - x) * punchForce * (punchRadius - distance),
y: (block.position.y - y) * punchForce * (punchRadius - distance)
};
Body.applyForce(block, block.position, force);
// Add score for hitting blocks
if (distance < punchRadius / 2) {
score += 10;
} else {
score += 5;
}
scoreElement.textContent = `Score: ${score}`;
}
});
}
// Reset game
function resetGame() {
blocks.forEach(block => {
World.remove(world, block);
});
blocks.length = 0;
score = 0;
scoreElement.textContent = `Score: ${score}`;
for (let i = 0; i < 10; i++) {
createBlock();
}
}
// Event listeners
document.addEventListener('click', (e) => {
punch(e.clientX, e.clientY);
});
document.addEventListener('keydown', (e) => {
if (e.code === 'Space') {
resetGame();
}
});
// Window resize handler
window.addEventListener('resize', () => {
render.options.width = window.innerWidth;
render.options.height = window.innerHeight;
Body.setPosition(ground, { x: window.innerWidth / 2, y: window.innerHeight - 20 });
Body.setVertices(ground, [
{ x: 0, y: window.innerHeight - 40 },
{ x: window.innerWidth, y: window.innerHeight - 40 },
{ x: window.innerWidth, y: window.innerHeight },
{ x: 0, y: window.innerHeight }
]);
Body.setPosition(leftWall, { x: 0, y: window.innerHeight / 2 });
Body.setVertices(leftWall, [
{ x: -20, y: 0 },
{ x: 20, y: 0 },
{ x: 20, y: window.innerHeight },
{ x: -20, y: window.innerHeight }
]);
Body.setPosition(rightWall, { x: window.innerWidth, y: window.innerHeight / 2 });
Body.setVertices(rightWall, [
{ x: window.innerWidth - 20, y: 0 },
{ x: window.innerWidth + 20, y: 0 },
{ x: window.innerWidth + 20, y: window.innerHeight },
{ x: window.innerWidth - 20, y: window.innerHeight }
]);
});
// Start the engine and renderer
Engine.run(engine);
Render.run(render);
// Initial setup
resetGame();
README.md:
# Knock