-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSpaceInvaders.js
128 lines (109 loc) · 3.62 KB
/
SpaceInvaders.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import React, { useEffect, useRef, useState } from 'react';
const SpaceInvaders = () => {
const canvasRef = useRef(null);
const [spaceship, setSpaceship] = useState({ x: 375, y: 550, width: 50, height: 20 });
const [aliens, setAliens] = useState([]);
const [bullets, setBullets] = useState([]);
const [keys, setKeys] = useState({ left: false, right: false });
useEffect(() => {
// Initialize aliens
const initialAliens = [];
for (let row = 0; row < 3; row++) {
for (let col = 0; col < 10; col++) {
initialAliens.push({
x: 30 + col * 60,
y: 30 + row * 30,
width: 40,
height: 30
});
}
}
setAliens(initialAliens);
}, []);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
const updateGame = () => {
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Update spaceship position
setSpaceship((prev) => ({
...prev,
x: prev.x + (keys.left ? -5 : keys.right ? 5 : 0)
}));
// Draw spaceship
ctx.fillStyle = 'white';
ctx.fillRect(spaceship.x, spaceship.y, spaceship.width, spaceship.height);
// Update bullets
setBullets((prev) => {
const updatedBullets = prev.map(bullet => ({
...bullet,
y: bullet.y - 5
}));
return updatedBullets.filter(bullet => bullet.y > 0);
});
// Draw bullets
ctx.fillStyle = 'red';
bullets.forEach(bullet => {
ctx.fillRect(bullet.x, bullet.y, 5, 15);
});
// Update aliens
setAliens((prev) => {
// Move aliens down
return prev.map(alien => ({
...alien,
y: alien.y + 0.1
}));
});
// Draw aliens
ctx.fillStyle = 'green';
aliens.forEach(alien => {
ctx.fillRect(alien.x, alien.y, alien.width, alien.height);
});
// Check for collisions
setAliens((prevAliens) => {
return prevAliens.filter((alien) => {
const isHit = bullets.some(bullet =>
bullet.x < alien.x + alien.width &&
bullet.x + 5 > alien.x &&
bullet.y < alien.y + alien.height &&
bullet.y + 15 > alien.y
);
if (isHit) {
setBullets(prev => prev.filter(b => !(
b.x < alien.x + alien.width &&
b.x + 5 > alien.x &&
b.y < alien.y + alien.height &&
b.y + 15 > alien.y
)));
}
return !isHit;
});
});
// Request next frame
requestAnimationFrame(updateGame);
};
updateGame();
}, [spaceship, bullets, aliens, keys]);
useEffect(() => {
const handleKeyDown = (e) => {
if (e.key === 'ArrowLeft') setKeys(prev => ({ ...prev, left: true }));
if (e.key === 'ArrowRight') setKeys(prev => ({ ...prev, right: true }));
if (e.key === ' ') {
setBullets(prev => [...prev, { x: spaceship.x + spaceship.width / 2 - 2.5, y: spaceship.y }]);
}
};
const handleKeyUp = (e) => {
if (e.key === 'ArrowLeft') setKeys(prev => ({ ...prev, left: false }));
if (e.key === 'ArrowRight') setKeys(prev => ({ ...prev, right: false }));
};
window.addEventListener('keydown', handleKeyDown);
window.addEventListener('keyup', handleKeyUp);
return () => {
window.removeEventListener('keydown', handleKeyDown);
window.removeEventListener('keyup', handleKeyUp);
};
}, [spaceship]);
return <canvas ref={canvasRef} width={800} height={600} style={{ border: '1px solid black' }} />;
};
export default SpaceInvaders;