cutechicken
commited on
Update index.html
Browse files- index.html +29 -39
index.html
CHANGED
@@ -24,13 +24,14 @@
|
|
24 |
}
|
25 |
#weaponInfo {
|
26 |
position: fixed;
|
27 |
-
top:
|
28 |
right: 10px;
|
29 |
color: white;
|
30 |
background: rgba(0,0,0,0.7);
|
31 |
padding: 10px;
|
32 |
border-radius: 5px;
|
33 |
z-index: 1000;
|
|
|
34 |
}
|
35 |
.button {
|
36 |
position: fixed;
|
@@ -83,7 +84,9 @@
|
|
83 |
enemyImg.src = 'enemy.png';
|
84 |
|
85 |
// Audio
|
86 |
-
const
|
|
|
|
|
87 |
|
88 |
// Game state
|
89 |
let currentRound = 1;
|
@@ -97,13 +100,15 @@
|
|
97 |
const weapons = {
|
98 |
cannon: {
|
99 |
fireRate: 1000,
|
100 |
-
damage: 0.
|
101 |
-
bulletSize: 5
|
|
|
102 |
},
|
103 |
machinegun: {
|
104 |
fireRate: 200,
|
105 |
damage: 0.05,
|
106 |
-
bulletSize: 2
|
|
|
107 |
}
|
108 |
};
|
109 |
|
@@ -113,18 +118,12 @@
|
|
113 |
y: canvas.height/2,
|
114 |
speed: 5,
|
115 |
angle: 0,
|
116 |
-
width:
|
117 |
-
height:
|
118 |
health: 1000,
|
119 |
maxHealth: 1000
|
120 |
};
|
121 |
|
122 |
-
function drawBackground() {
|
123 |
-
const pattern = ctx.createPattern(backgroundImg, 'repeat');
|
124 |
-
ctx.fillStyle = pattern;
|
125 |
-
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
126 |
-
}
|
127 |
-
|
128 |
class Enemy {
|
129 |
constructor() {
|
130 |
this.x = Math.random() * canvas.width;
|
@@ -136,26 +135,23 @@
|
|
136 |
this.shootInterval = 2000;
|
137 |
this.angle = 0;
|
138 |
this.moveAngle = Math.random() * Math.PI * 2;
|
|
|
|
|
139 |
}
|
140 |
|
141 |
update() {
|
142 |
-
// Movement
|
143 |
this.x += Math.cos(this.moveAngle) * this.speed;
|
144 |
this.y += Math.sin(this.moveAngle) * this.speed;
|
145 |
|
146 |
-
// Bounds check
|
147 |
if(this.x < 0 || this.x > canvas.width) this.moveAngle = Math.PI - this.moveAngle;
|
148 |
if(this.y < 0 || this.y > canvas.height) this.moveAngle = -this.moveAngle;
|
149 |
|
150 |
-
// Random direction change
|
151 |
if(Math.random() < 0.02) {
|
152 |
this.moveAngle = Math.random() * Math.PI * 2;
|
153 |
}
|
154 |
|
155 |
-
// Aim at player
|
156 |
this.angle = Math.atan2(player.y - this.y, player.x - this.x);
|
157 |
|
158 |
-
// Shooting
|
159 |
const now = Date.now();
|
160 |
if (now - this.lastShot > this.shootInterval) {
|
161 |
this.shoot();
|
@@ -164,7 +160,7 @@
|
|
164 |
}
|
165 |
|
166 |
shoot() {
|
167 |
-
|
168 |
bullets.push({
|
169 |
x: this.x,
|
170 |
y: this.y,
|
@@ -176,6 +172,12 @@
|
|
176 |
}
|
177 |
}
|
178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
function initRound() {
|
180 |
enemies = [];
|
181 |
for(let i = 0; i < 5 * currentRound; i++) {
|
@@ -201,10 +203,10 @@
|
|
201 |
const weapon = weapons[currentWeapon];
|
202 |
const now = Date.now();
|
203 |
if (keys[' '] && now - lastShot > weapon.fireRate) {
|
204 |
-
|
205 |
bullets.push({
|
206 |
-
x: player.x,
|
207 |
-
y: player.y,
|
208 |
angle: player.angle,
|
209 |
speed: 10,
|
210 |
isEnemy: false,
|
@@ -222,22 +224,18 @@
|
|
222 |
function updateGame() {
|
223 |
if(gameOver) return;
|
224 |
|
225 |
-
// Player movement
|
226 |
if(keys['w']) player.y -= player.speed;
|
227 |
if(keys['s']) player.y += player.speed;
|
228 |
if(keys['a']) player.x -= player.speed;
|
229 |
if(keys['d']) player.x += player.speed;
|
230 |
|
231 |
-
// Keep player in bounds
|
232 |
player.x = Math.max(player.width/2, Math.min(canvas.width - player.width/2, player.x));
|
233 |
player.y = Math.max(player.height/2, Math.min(canvas.height - player.height/2, player.y));
|
234 |
|
235 |
fireBullet();
|
236 |
|
237 |
-
// Update enemies
|
238 |
enemies.forEach(enemy => enemy.update());
|
239 |
|
240 |
-
// Update bullets
|
241 |
bullets = bullets.filter(bullet => {
|
242 |
bullet.x += Math.cos(bullet.angle) * bullet.speed;
|
243 |
bullet.y += Math.sin(bullet.angle) * bullet.speed;
|
@@ -245,7 +243,7 @@
|
|
245 |
if(!bullet.isEnemy) {
|
246 |
enemies = enemies.filter(enemy => {
|
247 |
const dist = Math.hypot(bullet.x - enemy.x, bullet.y - enemy.y);
|
248 |
-
if(dist <
|
249 |
enemy.health -= enemy.maxHealth * bullet.damage;
|
250 |
if(enemy.health <= 0) {
|
251 |
spawnHealthItem(enemy.x, enemy.y);
|
@@ -257,7 +255,7 @@
|
|
257 |
});
|
258 |
} else {
|
259 |
const dist = Math.hypot(bullet.x - player.x, bullet.y - player.y);
|
260 |
-
if(dist <
|
261 |
player.health -= 100;
|
262 |
if(player.health <= 0) {
|
263 |
gameOver = true;
|
@@ -271,17 +269,15 @@
|
|
271 |
bullet.y >= 0 && bullet.y <= canvas.height;
|
272 |
});
|
273 |
|
274 |
-
// Update items
|
275 |
items = items.filter(item => {
|
276 |
const dist = Math.hypot(item.x - player.x, item.y - player.y);
|
277 |
-
if(dist <
|
278 |
player.health = Math.min(player.health + 200, player.maxHealth);
|
279 |
return false;
|
280 |
}
|
281 |
return true;
|
282 |
});
|
283 |
|
284 |
-
// Check win condition
|
285 |
if(enemies.length === 0) {
|
286 |
if(currentRound < 10) {
|
287 |
nextRoundBtn.style.display = 'block';
|
@@ -306,27 +302,23 @@
|
|
306 |
function drawGame() {
|
307 |
drawBackground();
|
308 |
|
309 |
-
// Draw player
|
310 |
ctx.save();
|
311 |
ctx.translate(player.x, player.y);
|
312 |
ctx.rotate(player.angle);
|
313 |
ctx.drawImage(playerImg, -player.width/2, -player.height/2, player.width, player.height);
|
314 |
ctx.restore();
|
315 |
|
316 |
-
// Draw player health bar
|
317 |
drawHealthBar(canvas.width/2, 30, player.health, player.maxHealth, 200, 20, 'green');
|
318 |
|
319 |
-
// Draw enemies
|
320 |
enemies.forEach(enemy => {
|
321 |
ctx.save();
|
322 |
ctx.translate(enemy.x, enemy.y);
|
323 |
ctx.rotate(enemy.angle);
|
324 |
-
ctx.drawImage(enemyImg, -
|
325 |
ctx.restore();
|
326 |
-
drawHealthBar(enemy.x, enemy.y -
|
327 |
});
|
328 |
|
329 |
-
// Draw bullets
|
330 |
bullets.forEach(bullet => {
|
331 |
ctx.beginPath();
|
332 |
ctx.fillStyle = bullet.isEnemy ? 'red' : 'yellow';
|
@@ -334,7 +326,6 @@
|
|
334 |
ctx.fill();
|
335 |
});
|
336 |
|
337 |
-
// Draw health items
|
338 |
ctx.fillStyle = 'green';
|
339 |
items.forEach(item => {
|
340 |
ctx.beginPath();
|
@@ -342,7 +333,6 @@
|
|
342 |
ctx.fill();
|
343 |
});
|
344 |
|
345 |
-
// Draw round number
|
346 |
ctx.fillStyle = 'white';
|
347 |
ctx.font = '24px Arial';
|
348 |
ctx.fillText(`Round ${currentRound}/10`, 10, 30);
|
|
|
24 |
}
|
25 |
#weaponInfo {
|
26 |
position: fixed;
|
27 |
+
top: 150px;
|
28 |
right: 10px;
|
29 |
color: white;
|
30 |
background: rgba(0,0,0,0.7);
|
31 |
padding: 10px;
|
32 |
border-radius: 5px;
|
33 |
z-index: 1000;
|
34 |
+
font-size: 18px;
|
35 |
}
|
36 |
.button {
|
37 |
position: fixed;
|
|
|
84 |
enemyImg.src = 'enemy.png';
|
85 |
|
86 |
// Audio
|
87 |
+
const cannonSound = new Audio('firemn.ogg');
|
88 |
+
const machinegunSound = new Audio('firemg.ogg');
|
89 |
+
const enemyFireSound = new Audio('firemg.ogg');
|
90 |
|
91 |
// Game state
|
92 |
let currentRound = 1;
|
|
|
100 |
const weapons = {
|
101 |
cannon: {
|
102 |
fireRate: 1000,
|
103 |
+
damage: 0.50,
|
104 |
+
bulletSize: 5,
|
105 |
+
sound: cannonSound
|
106 |
},
|
107 |
machinegun: {
|
108 |
fireRate: 200,
|
109 |
damage: 0.05,
|
110 |
+
bulletSize: 2,
|
111 |
+
sound: machinegunSound
|
112 |
}
|
113 |
};
|
114 |
|
|
|
118 |
y: canvas.height/2,
|
119 |
speed: 5,
|
120 |
angle: 0,
|
121 |
+
width: 132,
|
122 |
+
height: 72,
|
123 |
health: 1000,
|
124 |
maxHealth: 1000
|
125 |
};
|
126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
class Enemy {
|
128 |
constructor() {
|
129 |
this.x = Math.random() * canvas.width;
|
|
|
135 |
this.shootInterval = 2000;
|
136 |
this.angle = 0;
|
137 |
this.moveAngle = Math.random() * Math.PI * 2;
|
138 |
+
this.width = 132;
|
139 |
+
this.height = 72;
|
140 |
}
|
141 |
|
142 |
update() {
|
|
|
143 |
this.x += Math.cos(this.moveAngle) * this.speed;
|
144 |
this.y += Math.sin(this.moveAngle) * this.speed;
|
145 |
|
|
|
146 |
if(this.x < 0 || this.x > canvas.width) this.moveAngle = Math.PI - this.moveAngle;
|
147 |
if(this.y < 0 || this.y > canvas.height) this.moveAngle = -this.moveAngle;
|
148 |
|
|
|
149 |
if(Math.random() < 0.02) {
|
150 |
this.moveAngle = Math.random() * Math.PI * 2;
|
151 |
}
|
152 |
|
|
|
153 |
this.angle = Math.atan2(player.y - this.y, player.x - this.x);
|
154 |
|
|
|
155 |
const now = Date.now();
|
156 |
if (now - this.lastShot > this.shootInterval) {
|
157 |
this.shoot();
|
|
|
160 |
}
|
161 |
|
162 |
shoot() {
|
163 |
+
enemyFireSound.cloneNode().play();
|
164 |
bullets.push({
|
165 |
x: this.x,
|
166 |
y: this.y,
|
|
|
172 |
}
|
173 |
}
|
174 |
|
175 |
+
function drawBackground() {
|
176 |
+
const pattern = ctx.createPattern(backgroundImg, 'repeat');
|
177 |
+
ctx.fillStyle = pattern;
|
178 |
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
179 |
+
}
|
180 |
+
|
181 |
function initRound() {
|
182 |
enemies = [];
|
183 |
for(let i = 0; i < 5 * currentRound; i++) {
|
|
|
203 |
const weapon = weapons[currentWeapon];
|
204 |
const now = Date.now();
|
205 |
if (keys[' '] && now - lastShot > weapon.fireRate) {
|
206 |
+
weapon.sound.cloneNode().play();
|
207 |
bullets.push({
|
208 |
+
x: player.x + Math.cos(player.angle) * 30,
|
209 |
+
y: player.y + Math.sin(player.angle) * 30,
|
210 |
angle: player.angle,
|
211 |
speed: 10,
|
212 |
isEnemy: false,
|
|
|
224 |
function updateGame() {
|
225 |
if(gameOver) return;
|
226 |
|
|
|
227 |
if(keys['w']) player.y -= player.speed;
|
228 |
if(keys['s']) player.y += player.speed;
|
229 |
if(keys['a']) player.x -= player.speed;
|
230 |
if(keys['d']) player.x += player.speed;
|
231 |
|
|
|
232 |
player.x = Math.max(player.width/2, Math.min(canvas.width - player.width/2, player.x));
|
233 |
player.y = Math.max(player.height/2, Math.min(canvas.height - player.height/2, player.y));
|
234 |
|
235 |
fireBullet();
|
236 |
|
|
|
237 |
enemies.forEach(enemy => enemy.update());
|
238 |
|
|
|
239 |
bullets = bullets.filter(bullet => {
|
240 |
bullet.x += Math.cos(bullet.angle) * bullet.speed;
|
241 |
bullet.y += Math.sin(bullet.angle) * bullet.speed;
|
|
|
243 |
if(!bullet.isEnemy) {
|
244 |
enemies = enemies.filter(enemy => {
|
245 |
const dist = Math.hypot(bullet.x - enemy.x, bullet.y - enemy.y);
|
246 |
+
if(dist < 40) {
|
247 |
enemy.health -= enemy.maxHealth * bullet.damage;
|
248 |
if(enemy.health <= 0) {
|
249 |
spawnHealthItem(enemy.x, enemy.y);
|
|
|
255 |
});
|
256 |
} else {
|
257 |
const dist = Math.hypot(bullet.x - player.x, bullet.y - player.y);
|
258 |
+
if(dist < 40) {
|
259 |
player.health -= 100;
|
260 |
if(player.health <= 0) {
|
261 |
gameOver = true;
|
|
|
269 |
bullet.y >= 0 && bullet.y <= canvas.height;
|
270 |
});
|
271 |
|
|
|
272 |
items = items.filter(item => {
|
273 |
const dist = Math.hypot(item.x - player.x, item.y - player.y);
|
274 |
+
if(dist < 40) {
|
275 |
player.health = Math.min(player.health + 200, player.maxHealth);
|
276 |
return false;
|
277 |
}
|
278 |
return true;
|
279 |
});
|
280 |
|
|
|
281 |
if(enemies.length === 0) {
|
282 |
if(currentRound < 10) {
|
283 |
nextRoundBtn.style.display = 'block';
|
|
|
302 |
function drawGame() {
|
303 |
drawBackground();
|
304 |
|
|
|
305 |
ctx.save();
|
306 |
ctx.translate(player.x, player.y);
|
307 |
ctx.rotate(player.angle);
|
308 |
ctx.drawImage(playerImg, -player.width/2, -player.height/2, player.width, player.height);
|
309 |
ctx.restore();
|
310 |
|
|
|
311 |
drawHealthBar(canvas.width/2, 30, player.health, player.maxHealth, 200, 20, 'green');
|
312 |
|
|
|
313 |
enemies.forEach(enemy => {
|
314 |
ctx.save();
|
315 |
ctx.translate(enemy.x, enemy.y);
|
316 |
ctx.rotate(enemy.angle);
|
317 |
+
ctx.drawImage(enemyImg, -enemy.width/2, -enemy.height/2, enemy.width, enemy.height);
|
318 |
ctx.restore();
|
319 |
+
drawHealthBar(enemy.x, enemy.y - 50, enemy.health, enemy.maxHealth, 60, 5, 'red');
|
320 |
});
|
321 |
|
|
|
322 |
bullets.forEach(bullet => {
|
323 |
ctx.beginPath();
|
324 |
ctx.fillStyle = bullet.isEnemy ? 'red' : 'yellow';
|
|
|
326 |
ctx.fill();
|
327 |
});
|
328 |
|
|
|
329 |
ctx.fillStyle = 'green';
|
330 |
items.forEach(item => {
|
331 |
ctx.beginPath();
|
|
|
333 |
ctx.fill();
|
334 |
});
|
335 |
|
|
|
336 |
ctx.fillStyle = 'white';
|
337 |
ctx.font = '24px Arial';
|
338 |
ctx.fillText(`Round ${currentRound}/10`, 10, 30);
|