@@ -8,6 +8,41 @@ let reconnecting = false;
88let ws = null;
99let lastGameStart = 0;
1010
11+ const enemyFireDelays = {
12+ vi: 3000,
13+ vim: 2000,
14+ neovim: 1000
15+ };
16+
17+
18+
19+ let quoteText = "";
20+ let quoteAuthor = "";
21+
22+ const fallbackQuotes = [
23+ { text: "Keep calm and code on.", author: "Anonymous" },
24+ { text: "There is no place like 127.0.0.1.", author: "Unknown" },
25+ { text: "First, solve the problem. Then, write the code.", author: "John Johnson" },
26+ { text: "Code is like humor. When you have to explain it, it’s bad.", author: "Cory House" },
27+ { text: "The best way to get a project done faster is to start sooner.", author: "Jim Highsmith" }
28+ ];
29+
30+ async function getMotivationalQuote() {
31+ try {
32+ const res = await fetch("https://api.quotable.io/random?maxLength=120&tags=technology|motivational|famous-quotes");
33+ const data = await res.json();
34+ quoteText = data.content || fallbackQuotes[0].text;
35+ quoteAuthor = data.author || fallbackQuotes[0].author;
36+ } catch (err) {
37+ const fallback = fallbackQuotes[Math.floor(Math.random() * fallbackQuotes.length)];
38+ quoteText = fallback.text;
39+ quoteAuthor = fallback.author;
40+ }
41+ }
42+
43+
44+
45+
1146function resizeCanvas() {
1247 const ratio = 4 / 3;
1348 const w = window.innerWidth;
@@ -48,23 +83,23 @@ document.addEventListener("visibilitychange", () => {
4883requestWakeLock();
4984
5085const pauseBtn = document.createElement("button");
51- pauseBtn.innerText = "⏸️ Pauza ";
86+ pauseBtn.innerText = "⏸️ Pause ";
5287pauseBtn.className = "game-button";
5388pauseBtn.style.right = "120px";
5489pauseBtn.style.top = "10px";
5590pauseBtn.onclick = () => paused = !paused;
5691document.body.appendChild(pauseBtn);
5792
5893const restartBtn = document.createElement("button");
59- restartBtn.innerText = "🔄 Restart ";
94+ restartBtn.innerText = "🔄 Reset ";
6095restartBtn.className = "game-button";
6196restartBtn.style.right = "10px";
6297restartBtn.style.top = "10px";
6398restartBtn.onclick = () => newGame();
6499document.body.appendChild(restartBtn);
65100
66101// resizeCanvas();
67-
102+ getMotivationalQuote();
68103
69104
70105const playerColors = ["white", "lime", "cyan", "orange", "violet"];
@@ -139,14 +174,42 @@ class Player {
139174 if (now - this.lastShot > 1000 && this.active && this.alive) {
140175 this.bullets.push({ x: this.x, y: this.y });
141176 this.lastShot = now;
142- } else if (gameOver
177+ } else if (gameOver) {
178+ newGame();
179+ }
180+ }
181+
182+ updateBullets() {
183+ this.bullets = this.bullets.filter(b => b.y > 0);
184+ this.bullets.forEach(b => b.y -= 7);
185+ ctx.fillStyle = this.color;
186+ this.bullets.forEach(b => ctx.fillRect(b.x - 2, b.y, 4, 10));
187+ }
188+
189+ takeHit() {
190+ if (!this.alive || this.lives <= 0) return;
191+ this.lives -= 1;
192+ this.alive = false;
193+ this.respawnTimer = Date.now();
194+ }
195+
196+ updateRespawn() {
197+ if (!this.alive && this.lives > 0) {
198+ const now = Date.now();
199+ if (now - this.respawnTimer >= 5000) {
200+ this.alive = true;
201+ }
202+ }
203+ }
204+ }
143205
144206class Enemy {
145207 constructor(x, y, type) {
146208 this.x = x;
147209 this.y = y;
148210 this.dx = 1;
149211 this.type = type;
212+ this.nextFireTime = Date.now() + Math.random() * enemyFireDelays[type];
150213 }
151214
152215 draw() {
@@ -167,6 +230,15 @@ class Enemy {
167230 this.y += 10;
168231 }
169232 }
233+
234+ canFire() {
235+ return Date.now() >= this.nextFireTime;
236+ }
237+
238+ resetFireCooldown() {
239+ this.nextFireTime = Date.now() + enemyFireDelays[this.type];
240+ }
241+
170242}
171243
172244
@@ -209,11 +281,16 @@ function randomColor() {
209281}
210282
211283function enemyFire() {
212- if (enemies.length === 0 || gameOver) return;
213- const shooter = enemies[Math.floor(Math.random() * enemies.length)];
214- enemyBullets.push({ x: shooter.x + 10, y: shooter.y + 10 });
284+ if (gameOver || enemies.length === 0) return;
285+ enemies.forEach(enemy => {
286+ if (enemy.canFire()) {
287+ enemyBullets.push({ x: enemy.x + 10, y: enemy.y + 10 });
288+ enemy.resetFireCooldown();
289+ }
290+ });
215291}
216292
293+
217294function drawHUD() {
218295 ctx.fillStyle = "white";
219296 ctx.font = "16px monospace";
@@ -286,6 +363,17 @@ function draw() {
286363 level++;
287364 createEnemies();
288365 updateFireRate();
366+
367+ [player1, player2].forEach(p => {
368+ if (p.lives < 3) {
369+ p.lives++;
370+ if (!p.alive) {
371+ p.alive = false;
372+ p.respawnTimer = Date.now();
373+ }
374+ }
375+ });
376+
289377 }
290378
291379 if (!player1.alive && player1.lives === 0 && !player2.alive && player2.lives === 0) {
0 commit comments