cutechicken commited on
Commit
5c67727
·
verified ·
1 Parent(s): 69185fd

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +251 -217
index.html CHANGED
@@ -67,7 +67,7 @@
67
  WASD - Move tank<br>
68
  Mouse - Aim<br>
69
  Space - Fire<br>
70
- C - Switch Weapon
71
  R - Toggle Auto-fire
72
  </div>
73
  <div id="weaponInfo">Current Weapon: Cannon</div>
@@ -75,25 +75,26 @@
75
  <button id="nextRound" class="button">Next Round</button>
76
  <button id="restart" class="button">Restart Game</button>
77
  <canvas id="gameCanvas"></canvas>
 
78
  <div id="shop" style="display:none; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); background:rgba(0,0,0,0.9); padding:20px; border-radius:10px; color:white; z-index:1000;">
79
- <h2>Tank Shop</h2>
80
- <div style="display:flex; gap:20px;">
81
- <div id="tank1" style="text-align:center;">
82
- <h3>PZ.IV</h3>
83
- <img src="player2.png" width="100" height="45">
84
- <p>300 Gold</p>
85
- <button onclick="buyTank('player2.png', 300, 'tank1')">Buy</button>
86
- </div>
87
- <div id="tank2" style="text-align:center;">
88
- <h3>TIGER</h3>
89
- <img src="player3.png" width="100" height="45">
90
- <p>500 Gold</p>
91
- <button onclick="buyTank('player3.png', 500, 'tank2')">Buy</button>
 
92
  </div>
93
  </div>
94
- </div>
95
- <button id="bossButton" class="button">Fight Boss!</button>
96
- <div id="winMessage" class="button" style="font-size: 72px; background: none;">You Win!</div>
97
 
98
  <script>
99
  const canvas = document.getElementById('gameCanvas');
@@ -102,8 +103,10 @@
102
  const restartBtn = document.getElementById('restart');
103
  const weaponInfo = document.getElementById('weaponInfo');
104
  const countdownEl = document.getElementById('countdown');
 
105
  canvas.width = window.innerWidth;
106
  canvas.height = window.innerHeight;
 
107
  // Game state
108
  let currentRound = 1;
109
  let gameOver = false;
@@ -117,23 +120,24 @@
117
  let autoFire = false;
118
  let gold = 0;
119
  let isBossStage = false;
120
-
121
  // Load assets
122
  const backgroundImg = new Image();
123
  backgroundImg.src = 'city.png';
124
  const playerImg = new Image();
125
  playerImg.src = 'player.png';
126
-
127
  const enemyImg = new Image();
128
  enemyImg.src = 'enemy.png';
 
129
  // Audio setup
130
  const cannonSound = new Audio('firemn.ogg');
131
  const machinegunSound = new Audio('firemg.ogg');
132
  const enemyFireSound = new Audio('fireenemy.ogg');
133
  const bgm = new Audio('BGM.ogg');
134
- const countSound = new Audio('count.ogg');
135
- bgm.loop = true;
136
  enemyFireSound.volume = 0.5;
 
137
  const weapons = {
138
  cannon: {
139
  fireRate: 1000,
@@ -148,6 +152,7 @@
148
  sound: machinegunSound
149
  }
150
  };
 
151
  // Player setup
152
  const player = {
153
  x: canvas.width/2,
@@ -159,103 +164,103 @@
159
  health: 1000,
160
  maxHealth: 1000
161
  };
162
- function startCountdown() {
163
- isCountingDown = true;
164
- countdownTime = 3;
165
- countdownEl.style.display = 'block';
166
- countdownEl.textContent = countdownTime;
167
- bgm.pause(); // BGM 일시정지
168
- countSound.play(); // 카운트다운 사운드 재생
169
- const countInterval = setInterval(() => {
170
- countdownTime--;
171
- if(countdownTime <= 0) {
172
- clearInterval(countInterval);
173
- countdownEl.style.display = 'none';
174
- isCountingDown = false;
175
- bgm.play(); // BGM 다시 재생
 
 
 
 
176
  }
177
- countdownEl.textContent = countdownTime > 0 ? countdownTime : 'GO!';
178
- }, 1000);
179
- }
180
  class Enemy {
181
- constructor(isBoss = false) {
182
- this.x = Math.random() * canvas.width;
183
- this.y = Math.random() * canvas.height;
184
- this.health = isBoss ? 5000 : 1000;
185
- this.maxHealth = this.health;
186
- this.speed = isBoss ? 1 : 2;
187
- this.lastShot = 0;
188
- this.shootInterval = isBoss ? 1000 : 1000;
189
- this.angle = 0;
190
- this.width = 100;
191
- this.height = 45;
192
- this.moveTimer = 0;
193
- this.moveInterval = Math.random() * 2000 + 1000;
194
- this.moveAngle = Math.random() * Math.PI * 2;
195
- this.isBoss = isBoss;
196
-
197
- if (isBoss) {
198
- this.enemyImg = new Image();
199
- this.enemyImg.src = 'boss.png';
200
- } else if (currentRound >= 7) {
201
- this.enemyImg = new Image();
202
- this.enemyImg.src = 'enemy3.png';
203
- } else if (currentRound >= 4) {
204
- this.enemyImg = new Image();
205
- this.enemyImg.src = 'enemy2.png';
206
- }
207
- }
208
 
209
  update() {
210
  if(isCountingDown) return;
211
  const now = Date.now();
212
 
213
- // Movement
214
  if (now - this.moveTimer > this.moveInterval) {
215
  this.moveAngle = Math.random() * Math.PI * 2;
216
  this.moveTimer = now;
217
  }
218
  this.x += Math.cos(this.moveAngle) * this.speed;
219
  this.y += Math.sin(this.moveAngle) * this.speed;
220
- // Bounds check
221
  this.x = Math.max(this.width/2, Math.min(canvas.width - this.width/2, this.x));
222
  this.y = Math.max(this.height/2, Math.min(canvas.height - this.height/2, this.y));
223
- // Aim at player
224
  this.angle = Math.atan2(player.y - this.y, player.x - this.x);
225
- // Shooting
226
  if (now - this.lastShot > this.shootInterval && !isCountingDown) {
227
  this.shoot();
228
  this.lastShot = now;
229
  }
230
  }
231
- shoot() {
232
- enemyFireSound.cloneNode().play();
233
- bullets.push({
234
- x: this.x + Math.cos(this.angle) * 30,
235
- y: this.y + Math.sin(this.angle) * 30,
236
- angle: this.angle,
237
- speed: 5,
238
- isEnemy: true,
239
- size: this.isBoss ? 5 : 3,
240
- damage: this.isBoss ? 200 : 100
241
- });
242
- }
243
- }
244
-
 
245
  function showShop() {
246
- document.getElementById('shop').style.display = 'block';
247
- }
248
-
249
- function buyTank(tankImg, cost, tankId) {
250
- if (gold >= cost) {
251
- gold -= cost;
252
- playerImg.src = tankImg;
253
- document.getElementById(tankId).style.display = 'none';
254
- document.getElementById('shop').style.display = 'none';
255
- initRound();
256
- }
257
- }
258
-
259
  function initRound() {
260
  enemies = [];
261
  for(let i = 0; i < 1 * currentRound; i++) {
@@ -266,20 +271,35 @@ function buyTank(tankImg, cost, tankId) {
266
  items = [];
267
  startCountdown();
268
  }
 
 
 
 
 
 
 
 
 
 
 
 
269
  canvas.addEventListener('mousemove', (e) => {
270
  player.angle = Math.atan2(e.clientY - player.y, e.clientX - player.x);
271
  });
 
272
  const keys = {};
273
- document.addEventListener('keydown', e => {
274
- keys[e.key] = true;
275
- if(e.key.toLowerCase() === 'c') {
276
- currentWeapon = currentWeapon === 'cannon' ? 'machinegun' : 'cannon';
277
- weaponInfo.textContent = `Current Weapon: ${currentWeapon.charAt(0).toUpperCase() + currentWeapon.slice(1)}`;
278
- } else if(e.key.toLowerCase() === 'r') {
279
- autoFire = !autoFire;
280
- }
281
- });
 
282
  document.addEventListener('keyup', e => keys[e.key] = false);
 
283
  function fireBullet() {
284
  if(isCountingDown) return;
285
  const weapon = weapons[currentWeapon];
@@ -299,16 +319,6 @@ function buyTank(tankImg, cost, tankId) {
299
  }
300
  }
301
 
302
- function startBossStage() {
303
- isBossStage = true;
304
- enemies = [];
305
- enemies.push(new Enemy(true));
306
- player.health = player.maxHealth;
307
- bullets = [];
308
- items = [];
309
- document.getElementById('bossButton').style.display = 'none';
310
- startCountdown();
311
- }
312
  function updateGame() {
313
  if(gameOver) return;
314
  if(!isCountingDown) {
@@ -320,9 +330,10 @@ function buyTank(tankImg, cost, tankId) {
320
  player.y = Math.max(player.height/2, Math.min(canvas.height - player.height/2, player.y));
321
  fireBullet();
322
  }
 
323
  enemies.forEach(enemy => enemy.update());
 
324
  if(!isCountingDown) {
325
- // Update bullets and collisions
326
  bullets = bullets.filter(bullet => {
327
  bullet.x += Math.cos(bullet.angle) * bullet.speed;
328
  bullet.y += Math.sin(bullet.angle) * bullet.speed;
@@ -343,7 +354,7 @@ function buyTank(tankImg, cost, tankId) {
343
  } else {
344
  const dist = Math.hypot(bullet.x - player.x, bullet.y - player.y);
345
  if(dist < 30) {
346
- player.health -= 100;
347
  if(player.health <= 0) {
348
  gameOver = true;
349
  restartBtn.style.display = 'block';
@@ -354,6 +365,7 @@ function buyTank(tankImg, cost, tankId) {
354
  return bullet.x >= 0 && bullet.x <= canvas.width &&
355
  bullet.y >= 0 && bullet.y <= canvas.height;
356
  });
 
357
  items = items.filter(item => {
358
  const dist = Math.hypot(item.x - player.x, item.y - player.y);
359
  if(dist < 30) {
@@ -362,8 +374,8 @@ function buyTank(tankImg, cost, tankId) {
362
  }
363
  return true;
364
  });
365
- if(enemies.length === 0) {
366
- //추가된 부분
367
  if (!isBossStage) {
368
  if(currentRound < 10) {
369
  nextRoundBtn.style.display = 'block';
@@ -374,103 +386,125 @@ function buyTank(tankImg, cost, tankId) {
374
  } else {
375
  gameOver = true;
376
  document.getElementById('winMessage').style.display = 'block';
377
- restartBtn.style.display = 'block';
378
- bgm.pause();
379
- }
380
- }
381
- }
382
- }
383
- function spawnHealthItem(x, y) {
384
- items.push({x, y});
385
- }
386
- function drawHealthBar(x, y, health, maxHealth, width, height, color) {
387
- ctx.fillStyle = '#333';
388
- ctx.fillRect(x - width/2, y - height/2, width, height);
389
- ctx.fillStyle = color;
390
- ctx.fillRect(x - width/2, y - height/2, width * (health/maxHealth), height);
391
- }
392
- function drawGame() {
393
- ctx.clearRect(0, 0, canvas.width, canvas.height);
394
- const pattern = ctx.createPattern(backgroundImg, 'repeat');
395
- ctx.fillStyle = pattern;
396
- ctx.fillRect(0, 0, canvas.width, canvas.height);
397
- // Draw all game objects
398
- ctx.save();
399
- ctx.translate(player.x, player.y);
400
- ctx.rotate(player.angle);
401
- ctx.drawImage(playerImg, -player.width/2, -player.height/2, player.width, player.height);
402
- ctx.restore();
403
- drawHealthBar(canvas.width/2, 30, player.health, player.maxHealth, 200, 20, 'green');
404
- enemies.forEach(enemy => {
405
- ctx.save();
406
- ctx.translate(enemy.x, enemy.y);
407
- ctx.rotate(enemy.angle);
408
- ctx.drawImage(enemyImg, -enemy.width/2, -enemy.height/2, enemy.width, enemy.height);
409
- ctx.restore();
410
- drawHealthBar(enemy.x, enemy.y - 40, enemy.health, enemy.maxHealth, 60, 5, 'red');
411
- });
412
- bullets.forEach(bullet => {
413
- ctx.beginPath();
414
- ctx.fillStyle = bullet.isEnemy ? 'red' : 'blue';
415
- ctx.arc(bullet.x, bullet.y, bullet.size, 0, Math.PI * 2);
416
- ctx.fill();
417
- });
418
- items.forEach(item => {
419
- ctx.beginPath();
420
- ctx.fillStyle = 'green';
421
- ctx.arc(item.x, item.y, 10, 0, Math.PI * 2);
422
- ctx.fill();
423
- });
424
- ctx.fillStyle = 'white';
425
- ctx.font = '24px Arial';
426
- ctx.fillText(`Round ${currentRound}/10`, 10, 30);
427
- if(isCountingDown) {
428
- ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
429
- ctx.fillRect(0, 0, canvas.width, canvas.height);
430
- ctx.fillStyle = 'white';
431
- //추가된 부분
432
- ctx.font = '24px Arial';
433
- ctx.fillText(`Round ${currentRound}/10`, 10, 30);
434
- ctx.fillText(`Gold: ${gold}`, 10, 60);
435
- }
436
- }
437
- function gameLoop() {
438
- updateGame();
439
- drawGame();
440
- requestAnimationFrame(gameLoop);
441
- }
442
- nextRoundBtn.addEventListener('click', () => {
443
- currentRound++;
444
- nextRoundBtn.style.display = 'none';
445
- initRound();
446
- });
447
- //추가된 부분
448
- restartBtn.addEventListener('click', () => {
449
- currentRound = 1;
450
- gameOver = false;
451
- isBossStage = false;
452
- gold = 0;
453
- restartBtn.style.display = 'none';
454
- document.getElementById('winMessage').style.display = 'none';
455
- document.getElementById('tank1').style.display = 'block';
456
- document.getElementById('tank2').style.display = 'block';
457
- playerImg.src = 'player.png';
458
- bgm.play();
459
- initRound();
460
- });
461
- Promise.all([
462
- new Promise(resolve => backgroundImg.onload = resolve),
463
- new Promise(resolve => playerImg.onload = resolve),
464
- new Promise(resolve => enemyImg.onload = resolve)
465
- ]).then(() => {
466
- initRound();
467
- gameLoop();
468
- bgm.play(); // 게임 시작시 BGM 재생
469
- });
470
- window.addEventListener('resize', () => {
471
- canvas.width = window.innerWidth;
472
- canvas.height = window.innerHeight;
473
- });
474
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
  </body>
476
  </html>
 
67
  WASD - Move tank<br>
68
  Mouse - Aim<br>
69
  Space - Fire<br>
70
+ C - Switch Weapon<br>
71
  R - Toggle Auto-fire
72
  </div>
73
  <div id="weaponInfo">Current Weapon: Cannon</div>
 
75
  <button id="nextRound" class="button">Next Round</button>
76
  <button id="restart" class="button">Restart Game</button>
77
  <canvas id="gameCanvas"></canvas>
78
+
79
  <div id="shop" style="display:none; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); background:rgba(0,0,0,0.9); padding:20px; border-radius:10px; color:white; z-index:1000;">
80
+ <h2>Tank Shop</h2>
81
+ <div style="display:flex; gap:20px;">
82
+ <div id="tank1" style="text-align:center;">
83
+ <h3>PZ.IV</h3>
84
+ <img src="player2.png" width="100" height="45">
85
+ <p>300 Gold</p>
86
+ <button onclick="buyTank('player2.png', 300, 'tank1')">Buy</button>
87
+ </div>
88
+ <div id="tank2" style="text-align:center;">
89
+ <h3>TIGER</h3>
90
+ <img src="player3.png" width="100" height="45">
91
+ <p>500 Gold</p>
92
+ <button onclick="buyTank('player3.png', 500, 'tank2')">Buy</button>
93
+ </div>
94
  </div>
95
  </div>
96
+ <button id="bossButton" class="button">Fight Boss!</button>
97
+ <div id="winMessage" class="button" style="font-size: 72px; background: none;">You Win!</div>
 
98
 
99
  <script>
100
  const canvas = document.getElementById('gameCanvas');
 
103
  const restartBtn = document.getElementById('restart');
104
  const weaponInfo = document.getElementById('weaponInfo');
105
  const countdownEl = document.getElementById('countdown');
106
+ const bossButton = document.getElementById('bossButton');
107
  canvas.width = window.innerWidth;
108
  canvas.height = window.innerHeight;
109
+
110
  // Game state
111
  let currentRound = 1;
112
  let gameOver = false;
 
120
  let autoFire = false;
121
  let gold = 0;
122
  let isBossStage = false;
123
+
124
  // Load assets
125
  const backgroundImg = new Image();
126
  backgroundImg.src = 'city.png';
127
  const playerImg = new Image();
128
  playerImg.src = 'player.png';
 
129
  const enemyImg = new Image();
130
  enemyImg.src = 'enemy.png';
131
+
132
  // Audio setup
133
  const cannonSound = new Audio('firemn.ogg');
134
  const machinegunSound = new Audio('firemg.ogg');
135
  const enemyFireSound = new Audio('fireenemy.ogg');
136
  const bgm = new Audio('BGM.ogg');
137
+ const countSound = new Audio('count.ogg');
138
+ bgm.loop = true;
139
  enemyFireSound.volume = 0.5;
140
+
141
  const weapons = {
142
  cannon: {
143
  fireRate: 1000,
 
152
  sound: machinegunSound
153
  }
154
  };
155
+
156
  // Player setup
157
  const player = {
158
  x: canvas.width/2,
 
164
  health: 1000,
165
  maxHealth: 1000
166
  };
167
+
168
+ function startCountdown() {
169
+ isCountingDown = true;
170
+ countdownTime = 3;
171
+ countdownEl.style.display = 'block';
172
+ countdownEl.textContent = countdownTime;
173
+ bgm.pause();
174
+ countSound.play();
175
+ const countInterval = setInterval(() => {
176
+ countdownTime--;
177
+ if(countdownTime <= 0) {
178
+ clearInterval(countInterval);
179
+ countdownEl.style.display = 'none';
180
+ isCountingDown = false;
181
+ bgm.play();
182
+ }
183
+ countdownEl.textContent = countdownTime > 0 ? countdownTime : 'GO!';
184
+ }, 1000);
185
  }
186
+
 
 
187
  class Enemy {
188
+ constructor(isBoss = false) {
189
+ this.x = Math.random() * canvas.width;
190
+ this.y = Math.random() * canvas.height;
191
+ this.health = isBoss ? 5000 : 1000;
192
+ this.maxHealth = this.health;
193
+ this.speed = isBoss ? 1 : 2;
194
+ this.lastShot = 0;
195
+ this.shootInterval = isBoss ? 1000 : 1000;
196
+ this.angle = 0;
197
+ this.width = 100;
198
+ this.height = 45;
199
+ this.moveTimer = 0;
200
+ this.moveInterval = Math.random() * 2000 + 1000;
201
+ this.moveAngle = Math.random() * Math.PI * 2;
202
+ this.isBoss = isBoss;
203
+
204
+ if (isBoss) {
205
+ this.enemyImg = new Image();
206
+ this.enemyImg.src = 'boss.png';
207
+ } else if (currentRound >= 7) {
208
+ this.enemyImg = new Image();
209
+ this.enemyImg.src = 'enemy3.png';
210
+ } else if (currentRound >= 4) {
211
+ this.enemyImg = new Image();
212
+ this.enemyImg.src = 'enemy2.png';
213
+ }
214
+ }
215
 
216
  update() {
217
  if(isCountingDown) return;
218
  const now = Date.now();
219
 
 
220
  if (now - this.moveTimer > this.moveInterval) {
221
  this.moveAngle = Math.random() * Math.PI * 2;
222
  this.moveTimer = now;
223
  }
224
  this.x += Math.cos(this.moveAngle) * this.speed;
225
  this.y += Math.sin(this.moveAngle) * this.speed;
 
226
  this.x = Math.max(this.width/2, Math.min(canvas.width - this.width/2, this.x));
227
  this.y = Math.max(this.height/2, Math.min(canvas.height - this.height/2, this.y));
 
228
  this.angle = Math.atan2(player.y - this.y, player.x - this.x);
229
+
230
  if (now - this.lastShot > this.shootInterval && !isCountingDown) {
231
  this.shoot();
232
  this.lastShot = now;
233
  }
234
  }
235
+
236
+ shoot() {
237
+ enemyFireSound.cloneNode().play();
238
+ bullets.push({
239
+ x: this.x + Math.cos(this.angle) * 30,
240
+ y: this.y + Math.sin(this.angle) * 30,
241
+ angle: this.angle,
242
+ speed: 5,
243
+ isEnemy: true,
244
+ size: this.isBoss ? 5 : 3,
245
+ damage: this.isBoss ? 200 : 100
246
+ });
247
+ }
248
+ }
249
+
250
  function showShop() {
251
+ document.getElementById('shop').style.display = 'block';
252
+ }
253
+
254
+ function buyTank(tankImg, cost, tankId) {
255
+ if (gold >= cost) {
256
+ gold -= cost;
257
+ playerImg.src = tankImg;
258
+ document.getElementById(tankId).style.display = 'none';
259
+ document.getElementById('shop').style.display = 'none';
260
+ initRound();
261
+ }
262
+ }
263
+
264
  function initRound() {
265
  enemies = [];
266
  for(let i = 0; i < 1 * currentRound; i++) {
 
271
  items = [];
272
  startCountdown();
273
  }
274
+
275
+ function startBossStage() {
276
+ isBossStage = true;
277
+ enemies = [];
278
+ enemies.push(new Enemy(true));
279
+ player.health = player.maxHealth;
280
+ bullets = [];
281
+ items = [];
282
+ document.getElementById('bossButton').style.display = 'none';
283
+ startCountdown();
284
+ }
285
+
286
  canvas.addEventListener('mousemove', (e) => {
287
  player.angle = Math.atan2(e.clientY - player.y, e.clientX - player.x);
288
  });
289
+
290
  const keys = {};
291
+ document.addEventListener('keydown', e => {
292
+ keys[e.key] = true;
293
+ if(e.key.toLowerCase() === 'c') {
294
+ currentWeapon = currentWeapon === 'cannon' ? 'machinegun' : 'cannon';
295
+ weaponInfo.textContent = `Current Weapon: ${currentWeapon.charAt(0).toUpperCase() + currentWeapon.slice(1)}`;
296
+ } else if(e.key.toLowerCase() === 'r') {
297
+ autoFire = !autoFire;
298
+ }
299
+ });
300
+
301
  document.addEventListener('keyup', e => keys[e.key] = false);
302
+
303
  function fireBullet() {
304
  if(isCountingDown) return;
305
  const weapon = weapons[currentWeapon];
 
319
  }
320
  }
321
 
 
 
 
 
 
 
 
 
 
 
322
  function updateGame() {
323
  if(gameOver) return;
324
  if(!isCountingDown) {
 
330
  player.y = Math.max(player.height/2, Math.min(canvas.height - player.height/2, player.y));
331
  fireBullet();
332
  }
333
+
334
  enemies.forEach(enemy => enemy.update());
335
+
336
  if(!isCountingDown) {
 
337
  bullets = bullets.filter(bullet => {
338
  bullet.x += Math.cos(bullet.angle) * bullet.speed;
339
  bullet.y += Math.sin(bullet.angle) * bullet.speed;
 
354
  } else {
355
  const dist = Math.hypot(bullet.x - player.x, bullet.y - player.y);
356
  if(dist < 30) {
357
+ player.health -= bullet.damage || 100;
358
  if(player.health <= 0) {
359
  gameOver = true;
360
  restartBtn.style.display = 'block';
 
365
  return bullet.x >= 0 && bullet.x <= canvas.width &&
366
  bullet.y >= 0 && bullet.y <= canvas.height;
367
  });
368
+
369
  items = items.filter(item => {
370
  const dist = Math.hypot(item.x - player.x, item.y - player.y);
371
  if(dist < 30) {
 
374
  }
375
  return true;
376
  });
377
+
378
+ if(enemies.length === 0) {
379
  if (!isBossStage) {
380
  if(currentRound < 10) {
381
  nextRoundBtn.style.display = 'block';
 
386
  } else {
387
  gameOver = true;
388
  document.getElementById('winMessage').style.display = 'block';
389
+ rest
390
+ gameOver = true;
391
+ document.getElementById('winMessage').style.display = 'block';
392
+ restartBtn.style.display = 'block';
393
+ bgm.pause();
394
+ }
395
+ }
396
+ }
397
+ }
398
+
399
+ function spawnHealthItem(x, y) {
400
+ items.push({x, y});
401
+ }
402
+
403
+ function drawHealthBar(x, y, health, maxHealth, width, height, color) {
404
+ ctx.fillStyle = '#333';
405
+ ctx.fillRect(x - width/2, y - height/2, width, height);
406
+ ctx.fillStyle = color;
407
+ ctx.fillRect(x - width/2, y - height/2, width * (health/maxHealth), height);
408
+ }
409
+
410
+ function drawGame() {
411
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
412
+ const pattern = ctx.createPattern(backgroundImg, 'repeat');
413
+ ctx.fillStyle = pattern;
414
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
415
+
416
+ // 플레이어 그리기
417
+ ctx.save();
418
+ ctx.translate(player.x, player.y);
419
+ ctx.rotate(player.angle);
420
+ ctx.drawImage(playerImg, -player.width/2, -player.height/2, player.width, player.height);
421
+ ctx.restore();
422
+
423
+ // 체력바
424
+ drawHealthBar(canvas.width/2, 30, player.health, player.maxHealth, 200, 20, 'green');
425
+
426
+ // 그리기
427
+ enemies.forEach(enemy => {
428
+ ctx.save();
429
+ ctx.translate(enemy.x, enemy.y);
430
+ ctx.rotate(enemy.angle);
431
+ const img = enemy.isBoss ? enemy.enemyImg : (enemy.enemyImg || enemyImg);
432
+ ctx.drawImage(img, -enemy.width/2, -enemy.height/2, enemy.width, enemy.height);
433
+ ctx.restore();
434
+ drawHealthBar(enemy.x, enemy.y - 40, enemy.health, enemy.maxHealth, 60, 5, 'red');
435
+ });
436
+
437
+ // 총알 그리기
438
+ bullets.forEach(bullet => {
439
+ ctx.beginPath();
440
+ ctx.fillStyle = bullet.isEnemy ? 'red' : 'blue';
441
+ ctx.arc(bullet.x, bullet.y, bullet.size, 0, Math.PI * 2);
442
+ ctx.fill();
443
+ });
444
+
445
+ // 아이템 그리기
446
+ items.forEach(item => {
447
+ ctx.beginPath();
448
+ ctx.fillStyle = 'green';
449
+ ctx.arc(item.x, item.y, 10, 0, Math.PI * 2);
450
+ ctx.fill();
451
+ });
452
+
453
+ // UI 그리기
454
+ ctx.fillStyle = 'white';
455
+ ctx.font = '24px Arial';
456
+ ctx.fillText(`Round ${currentRound}/10`, 10, 30);
457
+ ctx.fillText(`Gold: ${gold}`, 10, 60);
458
+
459
+ if(isCountingDown) {
460
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
461
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
462
+ }
463
+ }
464
+
465
+ function gameLoop() {
466
+ updateGame();
467
+ drawGame();
468
+ requestAnimationFrame(gameLoop);
469
+ }
470
+
471
+ nextRoundBtn.addEventListener('click', () => {
472
+ currentRound++;
473
+ nextRoundBtn.style.display = 'none';
474
+ document.getElementById('shop').style.display = 'none';
475
+ initRound();
476
+ });
477
+
478
+ bossButton.addEventListener('click', startBossStage);
479
+
480
+ restartBtn.addEventListener('click', () => {
481
+ currentRound = 1;
482
+ gameOver = false;
483
+ isBossStage = false;
484
+ gold = 0;
485
+ restartBtn.style.display = 'none';
486
+ document.getElementById('winMessage').style.display = 'none';
487
+ document.getElementById('tank1').style.display = 'block';
488
+ document.getElementById('tank2').style.display = 'block';
489
+ playerImg.src = 'player.png';
490
+ bgm.play();
491
+ initRound();
492
+ });
493
+
494
+ Promise.all([
495
+ new Promise(resolve => backgroundImg.onload = resolve),
496
+ new Promise(resolve => playerImg.onload = resolve),
497
+ new Promise(resolve => enemyImg.onload = resolve)
498
+ ]).then(() => {
499
+ initRound();
500
+ gameLoop();
501
+ bgm.play(); // 게임 시작시 BGM 재생
502
+ });
503
+
504
+ window.addEventListener('resize', () => {
505
+ canvas.width = window.innerWidth;
506
+ canvas.height = window.innerHeight;
507
+ });
508
+ </script>
509
  </body>
510
  </html>