Spaces:
Running
Running
cutechicken
commited on
Commit
β’
5eea967
1
Parent(s):
f0eec51
Update game.js
Browse files
game.js
CHANGED
@@ -32,69 +32,91 @@ class TankPlayer {
|
|
32 |
this.turretGroup = new THREE.Group();
|
33 |
this.health = MAX_HEALTH;
|
34 |
this.isLoaded = false;
|
35 |
-
this.ammo = 1;
|
36 |
-
this.maxAmmo = 1;
|
37 |
-
this.isReloading = false;
|
38 |
-
this.reloadTime = 3000;
|
39 |
this.lastShootTime = 0;
|
40 |
this.bullets = [];
|
41 |
this.obstacles = [];
|
42 |
this.scene = new THREE.Scene();
|
43 |
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
44 |
this.renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
}
|
46 |
-
|
47 |
createExplosionEffect(scene, position) {
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
transparent: true,
|
53 |
-
opacity: 1
|
54 |
-
});
|
55 |
-
const flash = new THREE.Mesh(flashGeometry, flashMaterial);
|
56 |
-
flash.position.copy(position);
|
57 |
-
scene.add(flash);
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
//
|
65 |
-
const
|
66 |
-
const
|
67 |
-
color:
|
68 |
transparent: true,
|
69 |
opacity: 1
|
70 |
});
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
const elevation = Math.random() * Math.PI - Math.PI / 2;
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
|
86 |
-
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
|
90 |
-
|
91 |
-
|
92 |
-
mesh: particle,
|
93 |
-
velocity: particle.velocity,
|
94 |
-
gravity: particle.gravity,
|
95 |
-
life: particle.life,
|
96 |
-
fadeRate: particle.fadeRate
|
97 |
-
});
|
98 |
}
|
99 |
|
100 |
// νλ° λ§ μ΄ννΈ
|
@@ -1491,6 +1513,11 @@ class Game {
|
|
1491 |
this.enemyLabels = new Map(); // μ λΌλ²¨μ μΆμ νκΈ° μν Map μΆκ°
|
1492 |
this.raycaster = new THREE.Raycaster();
|
1493 |
this.crosshair = document.getElementById('crosshair');
|
|
|
|
|
|
|
|
|
|
|
1494 |
document.getElementById('gameContainer').appendChild(this.renderer.domElement);
|
1495 |
|
1496 |
|
@@ -2600,49 +2627,59 @@ updateCrosshair() {
|
|
2600 |
}
|
2601 |
|
2602 |
animate() {
|
2603 |
-
|
2604 |
-
|
2605 |
-
|
2606 |
-
|
2607 |
-
|
2608 |
-
|
|
|
|
|
|
|
|
|
2609 |
|
2610 |
-
|
2611 |
-
|
|
|
2612 |
if (!this.isStarted) {
|
2613 |
this.renderer.render(this.scene, this.camera);
|
|
|
|
|
2614 |
return;
|
2615 |
}
|
2616 |
|
2617 |
-
|
2618 |
-
|
2619 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2620 |
|
2621 |
-
|
2622 |
-
|
2623 |
-
this.tank.update(this.mouse.x, this.mouse.y, this.scene);
|
2624 |
-
|
2625 |
-
const tankPosition = this.tank.getPosition();
|
2626 |
-
this.enemies.forEach(enemy => {
|
2627 |
-
enemy.update(tankPosition);
|
2628 |
-
|
2629 |
-
if (enemy.isLoaded && enemy.mesh.position.distanceTo(tankPosition) < ENEMY_CONFIG.ATTACK_RANGE) {
|
2630 |
-
enemy.shoot(tankPosition);
|
2631 |
-
}
|
2632 |
-
});
|
2633 |
-
this.updateEnemyLabels(); // μ λΌλ²¨ μ
λ°μ΄νΈ μΆκ°
|
2634 |
-
this.updateParticles();
|
2635 |
-
this.checkCollisions();
|
2636 |
-
this.updateUI();
|
2637 |
-
this.updateRadar(); // λ μ΄λ μ
λ°μ΄νΈ μΆκ°
|
2638 |
-
// ν¬λ‘μ€ν€μ΄ μ
λ°μ΄νΈ μΆκ°
|
2639 |
-
this.updateCrosshair();
|
2640 |
-
}
|
2641 |
-
|
2642 |
-
this.renderer.render(this.scene, this.camera);
|
2643 |
-
}
|
2644 |
-
}
|
2645 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2646 |
// Start game
|
2647 |
window.startGame = function() {
|
2648 |
document.getElementById('startScreen').style.display = 'none';
|
|
|
32 |
this.turretGroup = new THREE.Group();
|
33 |
this.health = MAX_HEALTH;
|
34 |
this.isLoaded = false;
|
35 |
+
this.ammo = 1;
|
36 |
+
this.maxAmmo = 1;
|
37 |
+
this.isReloading = false;
|
38 |
+
this.reloadTime = 3000;
|
39 |
this.lastShootTime = 0;
|
40 |
this.bullets = [];
|
41 |
this.obstacles = [];
|
42 |
this.scene = new THREE.Scene();
|
43 |
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
44 |
this.renderer = new THREE.WebGLRenderer({ antialias: true });
|
45 |
+
|
46 |
+
// FPS μ νμ μν μμ± μΆκ°
|
47 |
+
this.fps = 60;
|
48 |
+
this.frameInterval = 1000 / this.fps;
|
49 |
+
this.lastFrameTime = performance.now();
|
50 |
+
this.deltaTime = 0;
|
51 |
+
|
52 |
+
// λ λλ¬ FPS μ ν μ€μ
|
53 |
+
this.renderer.setAnimationLoop(null); // κΈ°λ³Έ μ λλ©μ΄μ
루ν λΉνμ±ν
|
54 |
}
|
55 |
+
|
56 |
createExplosionEffect(scene, position) {
|
57 |
+
// νμ¬ μκ° νμΈ
|
58 |
+
const currentTime = performance.now();
|
59 |
+
this.deltaTime += currentTime - this.lastFrameTime;
|
60 |
+
this.lastFrameTime = currentTime;
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
+
// FPS μ ν 체ν¬
|
63 |
+
if (this.deltaTime < this.frameInterval) {
|
64 |
+
return;
|
65 |
+
}
|
66 |
+
|
67 |
+
// νλ° μ€μ¬ νλμ
|
68 |
+
const flashGeometry = new THREE.SphereGeometry(3);
|
69 |
+
const flashMaterial = new THREE.MeshBasicMaterial({
|
70 |
+
color: 0xffff00,
|
71 |
transparent: true,
|
72 |
opacity: 1
|
73 |
});
|
74 |
+
const flash = new THREE.Mesh(flashGeometry, flashMaterial);
|
75 |
+
flash.position.copy(position);
|
76 |
+
scene.add(flash);
|
77 |
+
|
78 |
+
// νλ° νν°ν΄ (FPSμ λ§μΆ° μ
λ°μ΄νΈ)
|
79 |
+
const particleCount = Math.floor(30 * (this.deltaTime / this.frameInterval));
|
80 |
+
for (let i = 0; i < particleCount; i++) {
|
81 |
+
const size = Math.random() * 0.5 + 0.3;
|
82 |
+
const geometry = new THREE.SphereGeometry(size);
|
83 |
+
|
84 |
+
const colors = [0xff4500, 0xff8c00, 0xff0000, 0xffd700];
|
85 |
+
const material = new THREE.MeshBasicMaterial({
|
86 |
+
color: colors[Math.floor(Math.random() * colors.length)],
|
87 |
+
transparent: true,
|
88 |
+
opacity: 1
|
89 |
+
});
|
90 |
+
|
91 |
+
const particle = new THREE.Mesh(geometry, material);
|
92 |
+
particle.position.copy(position);
|
93 |
|
94 |
+
const speed = Math.random() * 0.5 + 0.3;
|
95 |
+
const angle = Math.random() * Math.PI * 2;
|
96 |
+
const elevation = Math.random() * Math.PI - Math.PI / 2;
|
|
|
97 |
|
98 |
+
particle.velocity = new THREE.Vector3(
|
99 |
+
Math.cos(angle) * Math.cos(elevation) * speed,
|
100 |
+
Math.sin(elevation) * speed,
|
101 |
+
Math.sin(angle) * Math.cos(elevation) * speed
|
102 |
+
);
|
103 |
|
104 |
+
particle.gravity = -0.015;
|
105 |
+
particle.life = Math.random() * 30 + 30;
|
106 |
+
particle.fadeRate = 0.97;
|
107 |
+
|
108 |
+
scene.add(particle);
|
109 |
+
window.gameInstance.particles.push({
|
110 |
+
mesh: particle,
|
111 |
+
velocity: particle.velocity,
|
112 |
+
gravity: particle.gravity,
|
113 |
+
life: particle.life,
|
114 |
+
fadeRate: particle.fadeRate
|
115 |
+
});
|
116 |
+
}
|
117 |
|
118 |
+
// deltaTime 리μ
|
119 |
+
this.deltaTime = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
}
|
121 |
|
122 |
// νλ° λ§ μ΄ννΈ
|
|
|
1513 |
this.enemyLabels = new Map(); // μ λΌλ²¨μ μΆμ νκΈ° μν Map μΆκ°
|
1514 |
this.raycaster = new THREE.Raycaster();
|
1515 |
this.crosshair = document.getElementById('crosshair');
|
1516 |
+
// FPS κ΄λ ¨ μμ± μΆκ°
|
1517 |
+
this.fps = 60;
|
1518 |
+
this.frameInterval = 1000 / this.fps;
|
1519 |
+
this.lastFrameTime = performance.now();
|
1520 |
+
this.deltaTime = 0;
|
1521 |
document.getElementById('gameContainer').appendChild(this.renderer.domElement);
|
1522 |
|
1523 |
|
|
|
2627 |
}
|
2628 |
|
2629 |
animate() {
|
2630 |
+
if (this.isGameOver) {
|
2631 |
+
if (this.animationFrameId) {
|
2632 |
+
cancelAnimationFrame(this.animationFrameId);
|
2633 |
+
}
|
2634 |
+
return;
|
2635 |
+
}
|
2636 |
+
|
2637 |
+
const currentTime = performance.now();
|
2638 |
+
this.deltaTime += currentTime - this.lastFrameTime;
|
2639 |
+
this.lastFrameTime = currentTime;
|
2640 |
|
2641 |
+
// FPS μ νμ μν νλ μ μ€ν΅
|
2642 |
+
if (this.deltaTime >= this.frameInterval) {
|
2643 |
+
// κ²μμ΄ μμλμ§ μμμΌλ©΄ λ λλ§λ§ μν
|
2644 |
if (!this.isStarted) {
|
2645 |
this.renderer.render(this.scene, this.camera);
|
2646 |
+
this.deltaTime = Math.min(this.deltaTime - this.frameInterval, this.frameInterval);
|
2647 |
+
this.animationFrameId = requestAnimationFrame(() => this.animate());
|
2648 |
return;
|
2649 |
}
|
2650 |
|
2651 |
+
// νλ μ μ
λ°μ΄νΈ
|
2652 |
+
if (!this.isLoading) {
|
2653 |
+
this.handleMovement();
|
2654 |
+
this.tank.update(this.mouse.x, this.mouse.y, this.scene);
|
2655 |
+
|
2656 |
+
const tankPosition = this.tank.getPosition();
|
2657 |
+
this.enemies.forEach(enemy => {
|
2658 |
+
enemy.update(tankPosition);
|
2659 |
+
|
2660 |
+
if (enemy.isLoaded && enemy.mesh.position.distanceTo(tankPosition) < ENEMY_CONFIG.ATTACK_RANGE) {
|
2661 |
+
enemy.shoot(tankPosition);
|
2662 |
+
}
|
2663 |
+
});
|
2664 |
+
|
2665 |
+
this.updateEnemyLabels();
|
2666 |
+
this.updateParticles();
|
2667 |
+
this.checkCollisions();
|
2668 |
+
this.updateUI();
|
2669 |
+
this.updateRadar();
|
2670 |
+
this.updateCrosshair();
|
2671 |
+
}
|
2672 |
|
2673 |
+
// λ λλ§
|
2674 |
+
this.renderer.render(this.scene, this.camera);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2675 |
|
2676 |
+
// deltaTime 리μ
(λ¨μ μκ° μ μ§)
|
2677 |
+
this.deltaTime = Math.min(this.deltaTime - this.frameInterval, this.frameInterval);
|
2678 |
+
}
|
2679 |
+
|
2680 |
+
// λ€μ νλ μ μμ²
|
2681 |
+
this.animationFrameId = requestAnimationFrame(() => this.animate());
|
2682 |
+
}
|
2683 |
// Start game
|
2684 |
window.startGame = function() {
|
2685 |
document.getElementById('startScreen').style.display = 'none';
|