Update index.html
Browse files- index.html +48 -32
index.html
CHANGED
@@ -201,21 +201,31 @@
|
|
201 |
}
|
202 |
|
203 |
class Effect {
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
|
|
|
|
|
|
|
|
218 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
class Enemy {
|
220 |
constructor(isBoss = false) {
|
221 |
this.x = Math.random() * canvas.width;
|
@@ -268,12 +278,13 @@
|
|
268 |
sound.play();
|
269 |
|
270 |
// 발사 이펙트 추가
|
271 |
-
|
272 |
this.x + Math.cos(this.angle) * 30,
|
273 |
this.y + Math.sin(this.angle) * 30,
|
274 |
-
500,
|
275 |
'fire',
|
276 |
-
this.angle
|
|
|
277 |
));
|
278 |
|
279 |
bullets.push({
|
@@ -362,13 +373,15 @@ function buyTank(tankImg, cost, tankId) {
|
|
362 |
if ((keys[' '] || autoFire) && now - lastShot > weapon.fireRate) {
|
363 |
weapon.sound.cloneNode().play();
|
364 |
// 발사 이펙트 추가
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
|
|
|
|
372 |
bullets.push({
|
373 |
x: player.x + Math.cos(player.angle) * 30,
|
374 |
y: player.y + Math.sin(player.angle) * 30,
|
@@ -520,14 +533,17 @@ function buyTank(tankImg, cost, tankId) {
|
|
520 |
ctx.fillText(`Gold: ${gold}`, 10, 60);
|
521 |
|
522 |
// 이펙트 그리기
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
|
|
|
|
|
|
531 |
|
532 |
if(isCountingDown) {
|
533 |
ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
|
|
|
201 |
}
|
202 |
|
203 |
class Effect {
|
204 |
+
constructor(x, y, duration, type, angle = 0, parent = null) {
|
205 |
+
this.x = x;
|
206 |
+
this.y = y;
|
207 |
+
this.startTime = Date.now();
|
208 |
+
this.duration = duration;
|
209 |
+
this.type = type;
|
210 |
+
this.angle = angle;
|
211 |
+
this.parent = parent; // 부모 유닛 (발사한 유닛)
|
212 |
+
this.offset = { x: Math.cos(angle) * 30, y: Math.sin(angle) * 30 }; // 부모로부터의 오프셋
|
213 |
+
this.img = new Image();
|
214 |
+
this.img.src = type === 'death' ? 'bang.png' : 'fire.png';
|
215 |
+
}
|
216 |
+
|
217 |
+
update() {
|
218 |
+
if(this.parent && this.type === 'fire') {
|
219 |
+
this.x = this.parent.x + this.offset.x;
|
220 |
+
this.y = this.parent.y + this.offset.y;
|
221 |
+
this.angle = this.parent.angle;
|
222 |
}
|
223 |
+
}
|
224 |
+
|
225 |
+
isExpired() {
|
226 |
+
return Date.now() - this.startTime > this.duration;
|
227 |
+
}
|
228 |
+
}
|
229 |
class Enemy {
|
230 |
constructor(isBoss = false) {
|
231 |
this.x = Math.random() * canvas.width;
|
|
|
278 |
sound.play();
|
279 |
|
280 |
// 발사 이펙트 추가
|
281 |
+
effects.push(new Effect(
|
282 |
this.x + Math.cos(this.angle) * 30,
|
283 |
this.y + Math.sin(this.angle) * 30,
|
284 |
+
500,
|
285 |
'fire',
|
286 |
+
this.angle,
|
287 |
+
this // 자신을 부모로 전달
|
288 |
));
|
289 |
|
290 |
bullets.push({
|
|
|
373 |
if ((keys[' '] || autoFire) && now - lastShot > weapon.fireRate) {
|
374 |
weapon.sound.cloneNode().play();
|
375 |
// 발사 이펙트 추가
|
376 |
+
effects.push(new Effect(
|
377 |
+
player.x + Math.cos(player.angle) * 30,
|
378 |
+
player.y + Math.sin(player.angle) * 30,
|
379 |
+
500,
|
380 |
+
'fire',
|
381 |
+
player.angle,
|
382 |
+
player // player를 부모로 전달
|
383 |
+
));
|
384 |
+
|
385 |
bullets.push({
|
386 |
x: player.x + Math.cos(player.angle) * 30,
|
387 |
y: player.y + Math.sin(player.angle) * 30,
|
|
|
533 |
ctx.fillText(`Gold: ${gold}`, 10, 60);
|
534 |
|
535 |
// 이펙트 그리기
|
536 |
+
effects = effects.filter(effect => !effect.isExpired());
|
537 |
+
effects.forEach(effect => {
|
538 |
+
effect.update(); // 이펙트 위치 업데이트
|
539 |
+
ctx.save();
|
540 |
+
ctx.translate(effect.x, effect.y);
|
541 |
+
if(effect.type === 'fire') ctx.rotate(effect.angle);
|
542 |
+
// bang.png는 1.5배 크게
|
543 |
+
const size = effect.type === 'death' ? 75 : 50; // death는 75px (1.5배), fire는 50px
|
544 |
+
ctx.drawImage(effect.img, -size/2, -size/2, size, size);
|
545 |
+
ctx.restore();
|
546 |
+
});
|
547 |
|
548 |
if(isCountingDown) {
|
549 |
ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
|