cutechicken commited on
Commit
f98dc5c
Β·
verified Β·
1 Parent(s): c6641c1

Update game.js

Browse files
Files changed (1) hide show
  1. game.js +90 -194
game.js CHANGED
@@ -1884,62 +1884,46 @@ class Game {
1884
  });
1885
  }
1886
 
1887
- // μƒˆλ‘œμš΄ λ©”μ„œλ“œ: 크고 ν™”λ €ν•œ μ§€λ©΄ 좩돌 효과
1888
  createGroundImpactEffect(position) {
1889
- // 메인 폭발 ν”Œλž˜μ‹œ
1890
- const flashGeometry = new THREE.SphereGeometry(15, 16, 16);
1891
  const flashMaterial = new THREE.MeshBasicMaterial({
1892
  color: 0xffaa00,
1893
  emissive: 0xffaa00,
1894
- emissiveIntensity: 3.0,
1895
  transparent: true,
1896
- opacity: 1.0
1897
  });
1898
 
1899
  const flash = new THREE.Mesh(flashGeometry, flashMaterial);
1900
  flash.position.copy(position);
1901
- flash.position.y = 2; // μ§€λ©΄μ—μ„œ μ•½κ°„ μœ„
1902
  this.scene.add(flash);
1903
 
1904
- // 좩격파 링
1905
- const ringGeometry = new THREE.RingGeometry(1, 15, 32);
1906
- const ringMaterial = new THREE.MeshBasicMaterial({
1907
- color: 0xff6600,
1908
- side: THREE.DoubleSide,
1909
- transparent: true,
1910
- opacity: 0.8
1911
- });
1912
-
1913
- const shockwaveRing = new THREE.Mesh(ringGeometry, ringMaterial);
1914
- shockwaveRing.position.copy(position);
1915
- shockwaveRing.position.y = 1;
1916
- shockwaveRing.rotation.x = -Math.PI / 2;
1917
- this.scene.add(shockwaveRing);
1918
-
1919
- // 파편 νŒŒν‹°ν΄ (더 많이, 더 크게)
1920
- const particleCount = 30;
1921
  const particles = [];
1922
- const debris = [];
1923
 
1924
  for (let i = 0; i < particleCount; i++) {
1925
  // λΆˆκ½ƒ νŒŒν‹°ν΄
1926
- const particleGeometry = new THREE.SphereGeometry(1 + Math.random(), 6, 6);
1927
  const particleMaterial = new THREE.MeshBasicMaterial({
1928
- color: Math.random() > 0.3 ? 0xffaa00 : 0xff0000,
1929
  emissive: 0xffaa00,
1930
- emissiveIntensity: 2.0,
1931
  transparent: true,
1932
  opacity: 1.0
1933
  });
1934
 
1935
  const particle = new THREE.Mesh(particleGeometry, particleMaterial);
1936
  particle.position.copy(position);
1937
- particle.position.y = 1;
1938
 
1939
- // 더 κ°•λ ₯ν•œ 폭발 속도
1940
  const angle = Math.random() * Math.PI * 2;
1941
- const speed = 50 + Math.random() * 150;
1942
- const upSpeed = 30 + Math.random() * 100;
1943
 
1944
  particle.velocity = new THREE.Vector3(
1945
  Math.cos(angle) * speed,
@@ -1947,225 +1931,134 @@ class Game {
1947
  Math.sin(angle) * speed
1948
  );
1949
 
1950
- particle.life = 1.5; // 더 였래 지속
1951
 
1952
  this.scene.add(particle);
1953
  particles.push(particle);
1954
-
1955
- // 흙 파편
1956
- if (i % 3 === 0) {
1957
- const debrisGeometry = new THREE.BoxGeometry(
1958
- 2 + Math.random() * 3,
1959
- 2 + Math.random() * 3,
1960
- 2 + Math.random() * 3
1961
- );
1962
- const debrisMaterial = new THREE.MeshLambertMaterial({
1963
- color: 0x4a3c28, // 흙색
1964
- transparent: true,
1965
- opacity: 1.0
1966
- });
1967
-
1968
- const debrisPiece = new THREE.Mesh(debrisGeometry, debrisMaterial);
1969
- debrisPiece.position.copy(position);
1970
- debrisPiece.position.y = 1;
1971
-
1972
- // νšŒμ „ μΆ”κ°€
1973
- debrisPiece.rotation.set(
1974
- Math.random() * Math.PI,
1975
- Math.random() * Math.PI,
1976
- Math.random() * Math.PI
1977
- );
1978
-
1979
- // 파편 속도
1980
- const debrisAngle = Math.random() * Math.PI * 2;
1981
- const debrisSpeed = 30 + Math.random() * 70;
1982
-
1983
- debrisPiece.velocity = new THREE.Vector3(
1984
- Math.cos(debrisAngle) * debrisSpeed,
1985
- 20 + Math.random() * 50,
1986
- Math.sin(debrisAngle) * debrisSpeed
1987
- );
1988
-
1989
- debrisPiece.angularVelocity = new THREE.Vector3(
1990
- (Math.random() - 0.5) * 10,
1991
- (Math.random() - 0.5) * 10,
1992
- (Math.random() - 0.5) * 10
1993
- );
1994
-
1995
- debrisPiece.life = 2.0;
1996
-
1997
- this.scene.add(debrisPiece);
1998
- debris.push(debrisPiece);
1999
- }
2000
  }
2001
 
2002
- // μ—°κΈ° 효과
2003
- const smokeCount = 8;
2004
- const smokes = [];
2005
 
2006
- for (let i = 0; i < smokeCount; i++) {
2007
- const smokeGeometry = new THREE.SphereGeometry(5 + Math.random() * 5, 8, 8);
2008
- const smokeMaterial = new THREE.MeshBasicMaterial({
2009
- color: 0x222222,
2010
  transparent: true,
2011
- opacity: 0.6
2012
  });
2013
 
2014
- const smoke = new THREE.Mesh(smokeGeometry, smokeMaterial);
2015
- smoke.position.copy(position);
2016
- smoke.position.y = 2 + Math.random() * 5;
2017
- smoke.position.x += (Math.random() - 0.5) * 10;
2018
- smoke.position.z += (Math.random() - 0.5) * 10;
2019
 
2020
- smoke.velocity = new THREE.Vector3(
2021
- (Math.random() - 0.5) * 10,
2022
- 5 + Math.random() * 15,
2023
- (Math.random() - 0.5) * 10
2024
  );
2025
 
2026
- smoke.life = 3.0;
2027
 
2028
- this.scene.add(smoke);
2029
- smokes.push(smoke);
2030
  }
2031
 
2032
- // μ§€λ©΄ ν¬λ ˆμ΄ν„° (μž„μ‹œ 효과)
2033
- const craterGeometry = new THREE.RingGeometry(5, 20, 16);
2034
- const craterMaterial = new THREE.MeshBasicMaterial({
2035
- color: 0x2a2a2a,
2036
  side: THREE.DoubleSide,
2037
  transparent: true,
2038
- opacity: 0.7
2039
  });
2040
 
2041
- const crater = new THREE.Mesh(craterGeometry, craterMaterial);
2042
- crater.position.copy(position);
2043
- crater.position.y = 0.1;
2044
- crater.rotation.x = -Math.PI / 2;
2045
- this.scene.add(crater);
2046
 
2047
  // μ• λ‹ˆλ©”μ΄μ…˜
2048
- const animateExplosion = () => {
2049
  let allDead = true;
2050
 
2051
- // 메인 ν”Œλž˜μ‹œ
2052
  if (flash.material.opacity > 0) {
2053
- flash.material.opacity -= 0.03;
2054
- flash.scale.multiplyScalar(1.15);
2055
  allDead = false;
2056
  } else if (flash.parent) {
2057
  this.scene.remove(flash);
2058
  }
2059
 
2060
- // 좩격파 링
2061
- if (shockwaveRing.material.opacity > 0) {
2062
- shockwaveRing.material.opacity -= 0.02;
2063
- shockwaveRing.scale.x += 0.5;
2064
- shockwaveRing.scale.y += 0.5;
2065
- allDead = false;
2066
- } else if (shockwaveRing.parent) {
2067
- this.scene.remove(shockwaveRing);
2068
- }
2069
-
2070
  // νŒŒν‹°ν΄ μ—…λ°μ΄νŠΈ
2071
- particles.forEach((particle, index) => {
2072
  if (particle.life > 0) {
2073
  allDead = false;
2074
- particle.life -= 0.02;
2075
 
2076
  // μœ„μΉ˜ μ—…λ°μ΄νŠΈ
2077
- particle.position.add(particle.velocity.clone().multiplyScalar(0.02));
2078
 
2079
  // 쀑λ ₯
2080
- particle.velocity.y -= 3;
2081
-
2082
- // 곡기 μ €ν•­
2083
- particle.velocity.multiplyScalar(0.98);
2084
 
2085
  // νŽ˜μ΄λ“œ 아웃
2086
- particle.material.opacity = particle.life;
2087
 
2088
  // 크기 κ°μ†Œ
2089
- const scale = particle.life * 0.8 + 0.2;
2090
  particle.scale.set(scale, scale, scale);
2091
  } else if (particle.parent) {
2092
  this.scene.remove(particle);
2093
  }
2094
  });
2095
 
2096
- // 파편 μ—…λ°μ΄νŠΈ
2097
- debris.forEach(piece => {
2098
- if (piece.life > 0) {
2099
- allDead = false;
2100
- piece.life -= 0.02;
2101
-
2102
- // μœ„μΉ˜ μ—…λ°μ΄νŠΈ
2103
- piece.position.add(piece.velocity.clone().multiplyScalar(0.02));
2104
-
2105
- // νšŒμ „
2106
- piece.rotation.x += piece.angularVelocity.x * 0.02;
2107
- piece.rotation.y += piece.angularVelocity.y * 0.02;
2108
- piece.rotation.z += piece.angularVelocity.z * 0.02;
2109
-
2110
- // 쀑λ ₯
2111
- piece.velocity.y -= 5;
2112
-
2113
- // μ§€λ©΄ 좩돌
2114
- if (piece.position.y <= 0) {
2115
- piece.position.y = 0;
2116
- piece.velocity.y *= -0.3;
2117
- piece.velocity.x *= 0.7;
2118
- piece.velocity.z *= 0.7;
2119
- }
2120
-
2121
- // νŽ˜μ΄λ“œ 아웃
2122
- piece.material.opacity = piece.life / 2;
2123
- } else if (piece.parent) {
2124
- this.scene.remove(piece);
2125
- }
2126
- });
2127
-
2128
- // μ—°κΈ° μ—…λ°μ΄νŠΈ
2129
- smokes.forEach(smoke => {
2130
- if (smoke.life > 0) {
2131
  allDead = false;
2132
- smoke.life -= 0.015;
2133
 
2134
  // μœ„μΉ˜ μ—…λ°μ΄νŠΈ
2135
- smoke.position.add(smoke.velocity.clone().multiplyScalar(0.02));
2136
 
2137
- // μƒμŠΉ
2138
- smoke.velocity.y *= 0.98;
2139
 
2140
  // ν™•μ‚°
2141
- smoke.scale.multiplyScalar(1.02);
2142
 
2143
  // νŽ˜μ΄λ“œ 아웃
2144
- smoke.material.opacity = smoke.life / 5;
2145
- } else if (smoke.parent) {
2146
- this.scene.remove(smoke);
2147
  }
2148
  });
2149
 
2150
- // ν¬λ ˆμ΄ν„° νŽ˜μ΄λ“œ
2151
- if (crater.material.opacity > 0) {
2152
- crater.material.opacity -= 0.005;
2153
  allDead = false;
2154
- } else if (crater.parent) {
2155
- this.scene.remove(crater);
2156
  }
2157
 
2158
  if (!allDead) {
2159
- requestAnimationFrame(animateExplosion);
2160
  }
2161
  };
2162
 
2163
- animateExplosion();
2164
 
2165
- // 좩돌 μ‚¬μš΄λ“œ μž¬μƒ
2166
  try {
2167
- const impactSound = new Audio('sounds/explode.ogg');
2168
- impactSound.volume = 0.4;
2169
  impactSound.play().catch(e => {});
2170
  } catch (e) {}
2171
  }
@@ -2181,15 +2074,16 @@ class Game {
2181
 
2182
  const distance = bullet.position.distanceTo(enemy.position);
2183
  if (distance < 90) { // 60μ—μ„œ 90으둜 증가 (100% ν™•λŒ€)
2184
- this.scene.remove(bullet);
2185
- this.fighter.bullets.splice(i, 1);
2186
-
2187
  // 히트 ν‘œμ‹œ μΆ”κ°€
2188
  this.showHitMarker(enemy.position);
2189
  // 피격 μ΄νŽ™νŠΈ μΆ”κ°€
2190
  this.createHitEffect(enemy.position);
2191
 
2192
- if (enemy.takeDamage(GAME_CONSTANTS.BULLET_DAMAGE)) { // 25 데미지
 
 
 
 
2193
  enemy.destroy();
2194
  this.enemies.splice(j, 1);
2195
  this.score += 100;
@@ -2201,20 +2095,22 @@ class Game {
2201
 
2202
  // 적 νƒ„ν™˜ vs ν”Œλ ˆμ΄μ–΄ 좩돌
2203
  this.enemies.forEach(enemy => {
2204
- enemy.bullets.forEach((bullet, index) => {
 
2205
  const distance = bullet.position.distanceTo(this.fighter.position);
2206
  if (distance < 100) { // 65μ—μ„œ 100으둜 증가 (100% ν™•λŒ€)
2207
- this.scene.remove(bullet);
2208
- enemy.bullets.splice(index, 1);
2209
-
2210
  // ν”Œλ ˆμ΄μ–΄ 피격 μ΄νŽ™νŠΈ
2211
  this.createHitEffect(this.fighter.position);
2212
 
2213
- if (this.fighter.takeDamage(GAME_CONSTANTS.BULLET_DAMAGE)) { // 25 데미지
 
 
 
 
2214
  this.endGame(false);
2215
  }
2216
  }
2217
- });
2218
  });
2219
  }
2220
 
 
1884
  });
1885
  }
1886
 
1887
+ // μƒˆλ‘œμš΄ λ©”μ„œλ“œ: νƒ„ν™˜ 크기의 μ§€λ©΄ 좩돌 효과
1888
  createGroundImpactEffect(position) {
1889
+ // μž‘μ€ ν”Œλž˜μ‹œ
1890
+ const flashGeometry = new THREE.SphereGeometry(3, 8, 8);
1891
  const flashMaterial = new THREE.MeshBasicMaterial({
1892
  color: 0xffaa00,
1893
  emissive: 0xffaa00,
1894
+ emissiveIntensity: 2.0,
1895
  transparent: true,
1896
+ opacity: 0.8
1897
  });
1898
 
1899
  const flash = new THREE.Mesh(flashGeometry, flashMaterial);
1900
  flash.position.copy(position);
1901
+ flash.position.y = 0.5;
1902
  this.scene.add(flash);
1903
 
1904
+ // μž‘μ€ 파편 νŒŒν‹°ν΄
1905
+ const particleCount = 10;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1906
  const particles = [];
 
1907
 
1908
  for (let i = 0; i < particleCount; i++) {
1909
  // λΆˆκ½ƒ νŒŒν‹°ν΄
1910
+ const particleGeometry = new THREE.SphereGeometry(0.3 + Math.random() * 0.3, 4, 4);
1911
  const particleMaterial = new THREE.MeshBasicMaterial({
1912
+ color: Math.random() > 0.5 ? 0xffaa00 : 0xff6600,
1913
  emissive: 0xffaa00,
1914
+ emissiveIntensity: 1.5,
1915
  transparent: true,
1916
  opacity: 1.0
1917
  });
1918
 
1919
  const particle = new THREE.Mesh(particleGeometry, particleMaterial);
1920
  particle.position.copy(position);
1921
+ particle.position.y = 0.2;
1922
 
1923
+ // μ λ‹Ήν•œ 속도
1924
  const angle = Math.random() * Math.PI * 2;
1925
+ const speed = 10 + Math.random() * 30;
1926
+ const upSpeed = 15 + Math.random() * 25;
1927
 
1928
  particle.velocity = new THREE.Vector3(
1929
  Math.cos(angle) * speed,
 
1931
  Math.sin(angle) * speed
1932
  );
1933
 
1934
+ particle.life = 0.5; // 0.5초 지속
1935
 
1936
  this.scene.add(particle);
1937
  particles.push(particle);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1938
  }
1939
 
1940
+ // μž‘μ€ λ¨Όμ§€ 효과
1941
+ const dustCount = 3;
1942
+ const dusts = [];
1943
 
1944
+ for (let i = 0; i < dustCount; i++) {
1945
+ const dustGeometry = new THREE.SphereGeometry(1 + Math.random() * 1, 6, 6);
1946
+ const dustMaterial = new THREE.MeshBasicMaterial({
1947
+ color: 0x8b7355,
1948
  transparent: true,
1949
+ opacity: 0.4
1950
  });
1951
 
1952
+ const dust = new THREE.Mesh(dustGeometry, dustMaterial);
1953
+ dust.position.copy(position);
1954
+ dust.position.y = 0.5;
1955
+ dust.position.x += (Math.random() - 0.5) * 2;
1956
+ dust.position.z += (Math.random() - 0.5) * 2;
1957
 
1958
+ dust.velocity = new THREE.Vector3(
1959
+ (Math.random() - 0.5) * 5,
1960
+ 3 + Math.random() * 5,
1961
+ (Math.random() - 0.5) * 5
1962
  );
1963
 
1964
+ dust.life = 0.8;
1965
 
1966
+ this.scene.add(dust);
1967
+ dusts.push(dust);
1968
  }
1969
 
1970
+ // 탄착점 마크
1971
+ const impactGeometry = new THREE.RingGeometry(0.5, 2, 8);
1972
+ const impactMaterial = new THREE.MeshBasicMaterial({
1973
+ color: 0x333333,
1974
  side: THREE.DoubleSide,
1975
  transparent: true,
1976
+ opacity: 0.5
1977
  });
1978
 
1979
+ const impact = new THREE.Mesh(impactGeometry, impactMaterial);
1980
+ impact.position.copy(position);
1981
+ impact.position.y = 0.05;
1982
+ impact.rotation.x = -Math.PI / 2;
1983
+ this.scene.add(impact);
1984
 
1985
  // μ• λ‹ˆλ©”μ΄μ…˜
1986
+ const animateImpact = () => {
1987
  let allDead = true;
1988
 
1989
+ // ν”Œλž˜μ‹œ
1990
  if (flash.material.opacity > 0) {
1991
+ flash.material.opacity -= 0.08;
1992
+ flash.scale.multiplyScalar(1.1);
1993
  allDead = false;
1994
  } else if (flash.parent) {
1995
  this.scene.remove(flash);
1996
  }
1997
 
 
 
 
 
 
 
 
 
 
 
1998
  // νŒŒν‹°ν΄ μ—…λ°μ΄νŠΈ
1999
+ particles.forEach(particle => {
2000
  if (particle.life > 0) {
2001
  allDead = false;
2002
+ particle.life -= 0.03;
2003
 
2004
  // μœ„μΉ˜ μ—…λ°μ΄νŠΈ
2005
+ particle.position.add(particle.velocity.clone().multiplyScalar(0.03));
2006
 
2007
  // 쀑λ ₯
2008
+ particle.velocity.y -= 2;
 
 
 
2009
 
2010
  // νŽ˜μ΄λ“œ 아웃
2011
+ particle.material.opacity = particle.life * 2;
2012
 
2013
  // 크기 κ°μ†Œ
2014
+ const scale = particle.life * 2;
2015
  particle.scale.set(scale, scale, scale);
2016
  } else if (particle.parent) {
2017
  this.scene.remove(particle);
2018
  }
2019
  });
2020
 
2021
+ // λ¨Όμ§€ μ—…λ°μ΄νŠΈ
2022
+ dusts.forEach(dust => {
2023
+ if (dust.life > 0) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2024
  allDead = false;
2025
+ dust.life -= 0.02;
2026
 
2027
  // μœ„μΉ˜ μ—…λ°μ΄νŠΈ
2028
+ dust.position.add(dust.velocity.clone().multiplyScalar(0.02));
2029
 
2030
+ // μƒμŠΉ 감속
2031
+ dust.velocity.y *= 0.95;
2032
 
2033
  // ν™•μ‚°
2034
+ dust.scale.multiplyScalar(1.03);
2035
 
2036
  // νŽ˜μ΄λ“œ 아웃
2037
+ dust.material.opacity = dust.life * 0.5;
2038
+ } else if (dust.parent) {
2039
+ this.scene.remove(dust);
2040
  }
2041
  });
2042
 
2043
+ // 탄착점 νŽ˜μ΄λ“œ
2044
+ if (impact.material.opacity > 0) {
2045
+ impact.material.opacity -= 0.01;
2046
  allDead = false;
2047
+ } else if (impact.parent) {
2048
+ this.scene.remove(impact);
2049
  }
2050
 
2051
  if (!allDead) {
2052
+ requestAnimationFrame(animateImpact);
2053
  }
2054
  };
2055
 
2056
+ animateImpact();
2057
 
2058
+ // μž‘μ€ 좩돌음
2059
  try {
2060
+ const impactSound = new Audio('sounds/hit.ogg');
2061
+ impactSound.volume = 0.2;
2062
  impactSound.play().catch(e => {});
2063
  } catch (e) {}
2064
  }
 
2074
 
2075
  const distance = bullet.position.distanceTo(enemy.position);
2076
  if (distance < 90) { // 60μ—μ„œ 90으둜 증가 (100% ν™•λŒ€)
 
 
 
2077
  // 히트 ν‘œμ‹œ μΆ”κ°€
2078
  this.showHitMarker(enemy.position);
2079
  // 피격 μ΄νŽ™νŠΈ μΆ”κ°€
2080
  this.createHitEffect(enemy.position);
2081
 
2082
+ // νƒ„ν™˜ μ œκ±°λŠ” μ΄νŽ™νŠΈ 생성 후에
2083
+ this.scene.remove(bullet);
2084
+ this.fighter.bullets.splice(i, 1);
2085
+
2086
+ if (enemy.takeDamage(GAME_CONSTANTS.BULLET_DAMAGE)) { // 50 데미지
2087
  enemy.destroy();
2088
  this.enemies.splice(j, 1);
2089
  this.score += 100;
 
2095
 
2096
  // 적 νƒ„ν™˜ vs ν”Œλ ˆμ΄μ–΄ 좩돌
2097
  this.enemies.forEach(enemy => {
2098
+ for (let index = enemy.bullets.length - 1; index >= 0; index--) {
2099
+ const bullet = enemy.bullets[index];
2100
  const distance = bullet.position.distanceTo(this.fighter.position);
2101
  if (distance < 100) { // 65μ—μ„œ 100으둜 증가 (100% ν™•λŒ€)
 
 
 
2102
  // ν”Œλ ˆμ΄μ–΄ 피격 μ΄νŽ™νŠΈ
2103
  this.createHitEffect(this.fighter.position);
2104
 
2105
+ // νƒ„ν™˜ 제거
2106
+ this.scene.remove(bullet);
2107
+ enemy.bullets.splice(index, 1);
2108
+
2109
+ if (this.fighter.takeDamage(GAME_CONSTANTS.BULLET_DAMAGE)) { // 50 데미지
2110
  this.endGame(false);
2111
  }
2112
  }
2113
+ }
2114
  });
2115
  }
2116