#gameCanvasContainer { display: flex; justify-content: center; align-items: center; background: black; }
#gameCanvas { border: 1px solid white; background: black; }
// Space Invaders Clone – Basic HTML5 Canvas Version
// This is a simple implementation. Elements are drawn with shapes, but I’ve commented where you can replace with images.
// Controls: Arrow Left/Right to move, Space to shoot.
// To customize: Search for “CUSTOMIZE” comments to swap in images from Canva (export as PNG with transparent background).
const canvas = document.getElementById(‘gameCanvas’);
const ctx = canvas.getContext(‘2d’);
// Game variables
let player = { x: canvas.width / 2 – 25, y: canvas.height – 50, width: 50, height: 30, speed: 5 };
let bullets = [];
let invaders = [];
let invaderDirection = 1; // 1 right, -1 left
let invaderSpeed = 1;
let score = 0;
let lives = 3;
let gameOver = false;
// Create invaders grid (5 rows, 11 columns)
function createInvaders() {
invaders = [];
for (let row = 0; row < 5; row++) {
for (let col = 0; col < 11; col++) {
invaders.push({
x: 50 + col * 60,
y: 50 + row * 40,
width: 40,
height: 30,
alive: true
});
}
}
}
createInvaders();
// Keyboard input
let keys = {};
window.addEventListener('keydown', (e) => { keys[e.key] = true; });
window.addEventListener(‘keyup’, (e) => { keys[e.key] = false; });
// Game loop
function update() {
if (gameOver) return;
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Move player
if (keys[‘ArrowLeft’] && player.x > 0) player.x -= player.speed;
if (keys[‘ArrowRight’] && player.x + player.width < canvas.width) player.x += player.speed;
// Shoot bullet
if (keys[' '] && !keys.shot) { // Prevent rapid fire
bullets.push({ x: player.x + player.width / 2 - 2.5, y: player.y, width: 5, height: 10, speed: 7 });
keys.shot = true;
}
if (!keys[' ']) keys.shot = false;
// Update bullets
bullets.forEach((bullet, index) => {
bullet.y -= bullet.speed;
if (bullet.y < 0) bullets.splice(index, 1);
// Check collision with invaders
invaders.forEach((invader, iIndex) => {
if (invader.alive &&
bullet.x < invader.x + invader.width &&
bullet.x + bullet.width > invader.x &&
bullet.y < invader.y + invader.height &&
bullet.y + bullet.height > invader.y) {
invader.alive = false;
bullets.splice(index, 1);
score += 10;
}
});
});
// Move invaders
let edgeHit = false;
invaders.forEach(invader => {
if (invader.alive) {
invader.x += invaderDirection * invaderSpeed;
if (invader.x + invader.width > canvas.width || invader.x < 0) edgeHit = true;
// Check if invader reaches player level
if (invader.y + invader.height >= player.y) {
lives–;
if (lives { if (invader.alive) invader.y += 20; });
}
// Invaders shoot (simple random chance)
if (Math.random() < 0.005) {
let shooter = invaders.filter(i => i.alive)[Math.floor(Math.random() * invaders.filter(i => i.alive).length)];
if (shooter) {
bullets.push({ x: shooter.x + shooter.width / 2 – 2.5, y: shooter.y + shooter.height, width: 5, height: 10, speed: -5, enemy: true });
}
}
// Enemy bullets hit player
bullets.forEach((bullet, index) => {
if (bullet.enemy) {
bullet.y += Math.abs(bullet.speed); // Move down
if (bullet.y > canvas.height) bullets.splice(index, 1);
if (bullet.x < player.x + player.width &&
bullet.x + bullet.width > player.x &&
bullet.y < player.y + player.height &&
bullet.y + bullet.height > player.y) {
lives–;
bullets.splice(index, 1);
if (lives !i.alive)) {
createInvaders();
invaderSpeed += 0.5; // Increase difficulty
}
// Draw player – CUSTOMIZE: Replace with image draw
ctx.fillStyle = ‘green’;
ctx.fillRect(player.x, player.y, player.width, player.height);
// Example for image: let playerImg = new Image(); playerImg.src = ‘your-son-face.png’; ctx.drawImage(playerImg, player.x, player.y, player.width, player.height);
// Draw bullets
ctx.fillStyle = ‘white’;
bullets.forEach(bullet => {
ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
});
// Draw invaders – CUSTOMIZE: Different shapes or images per row
invaders.forEach(invader => {
if (invader.alive) {
ctx.fillStyle = ‘red’;
ctx.fillRect(invader.x, invader.y, invader.width, invader.height);
// Example for image: let invaderImg = new Image(); invaderImg.src = ‘custom-invader.png’; ctx.drawImage(invaderImg, invader.x, invader.y, invader.width, invader.height);
}
});
// Draw score and lives
ctx.fillStyle = ‘white’;
ctx.font = ’20px Arial’;
ctx.fillText(`Score: ${score}`, 10, 30);
ctx.fillText(`Lives: ${lives}`, canvas.width – 100, 30);
if (gameOver) {
ctx.fillText(‘Game Over! Refresh to restart.’, canvas.width / 2 – 150, canvas.height / 2);
}
requestAnimationFrame(update);
}
update();