akhaliq HF Staff commited on
Commit
7bc1bae
·
verified ·
1 Parent(s): c3101d0

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +300 -179
index.html CHANGED
@@ -1,58 +1,105 @@
1
  <!DOCTYPE html>
2
  <html>
3
  <head>
4
- <title>Neon Runner</title>
5
  <style>
6
- body { margin: 0; overflow: hidden; touch-action: none; }
7
- #ui {
8
  position: fixed;
9
  top: 20px;
10
- left: 50%;
11
- transform: translateX(-50%);
12
- color: #0ff;
13
- font-family: Arial;
14
- text-align: center;
15
- pointer-events: none;
16
- text-shadow: 0 0 10px #0ff;
17
  }
18
- #restart {
 
19
  position: fixed;
20
  top: 50%;
21
  left: 50%;
22
  transform: translate(-50%, -50%);
23
- padding: 15px 30px;
24
- font-size: 24px;
25
- background: #00ffff;
26
- border: none;
27
- border-radius: 10px;
28
- cursor: pointer;
29
- display: none;
30
- box-shadow: 0 0 20px #0ff;
31
  }
32
  </style>
 
33
  </head>
34
  <body>
35
- <div id="ui">
 
 
36
  <div>SCORE: <span id="score">0</span></div>
37
  <div>COMBO: <span id="combo">x1</span></div>
38
  </div>
39
- <button id="restart">RESTART</button>
 
 
 
40
 
41
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
 
 
 
 
 
42
  <script>
43
- let scene, camera, renderer, player, particles;
44
- let obstacles = [];
45
  let powerUps = [];
46
- let velocity = 0;
 
 
47
  let score = 0;
48
  let combo = 1;
 
 
 
 
49
  const config = {
50
- GRAVITY: 0.02,
51
- JUMP_FORCE: 0.6,
52
- SPEED: 0.4,
53
- PARTICLE_COUNT: 30
 
54
  };
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  function init() {
57
  scene = new THREE.Scene();
58
  camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
@@ -61,220 +108,294 @@
61
  renderer.setClearColor(0x000000);
62
  document.body.appendChild(renderer.domElement);
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  // Lighting
65
- const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
66
  scene.add(ambientLight);
67
- const directionalLight = new THREE.DirectionalLight(0x00ffff, 1);
68
- directionalLight.position.set(0, 5, 5);
 
69
  scene.add(directionalLight);
70
 
71
- // Player
72
- const playerGeometry = new THREE.CapsuleGeometry(0.3, 0.6, 8, 16);
73
- const playerMaterial = new THREE.MeshPhongMaterial({
74
- color: 0x00ffff,
75
- emissive: 0x00ffff,
76
- emissiveIntensity: 0.5
 
77
  });
78
- player = new THREE.Mesh(playerGeometry, playerMaterial);
79
- player.position.set(0, 2, 0);
80
- scene.add(player);
81
 
82
- // Track
83
- createTrack();
84
- createParticleSystem();
85
-
86
- camera.position.set(0, 4, 7);
87
- camera.lookAt(0, 2, 0);
88
- }
89
 
90
- function createTrack() {
91
- const trackGeometry = new THREE.PlaneGeometry(40, 40);
92
- const trackTexture = new THREE.TextureLoader().load('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAJUlEQVQoU2NkYGD4z8DAwMgABXCJYARQic4H4gIiBC4hAAACCRAH6YGjSQAAAABJRU5ErkJggg==');
93
- const trackMaterial = new THREE.MeshPhongMaterial({
94
- color: 0x222222,
95
- emissive: 0x00ffff,
96
- emissiveIntensity: 0.1,
97
- map: trackTexture
98
- });
99
- const track = new THREE.Mesh(trackGeometry, trackMaterial);
100
- track.rotation.x = -Math.PI / 2;
101
- scene.add(track);
102
- }
103
-
104
- function createParticleSystem() {
105
- const particleGeometry = new THREE.BufferGeometry();
106
- const positions = [];
107
- for(let i = 0; i < config.PARTICLE_COUNT; i++) {
108
- positions.push(
109
- Math.random() * 20 - 10,
110
- 0.2,
111
- Math.random() * 20 - 10
112
  );
113
  }
114
- particleGeometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
115
- const particleMaterial = new THREE.PointsMaterial({
116
  size: 0.1,
117
- color: 0x00ffff,
118
  transparent: true,
119
- opacity: 0.6
120
  });
121
- particles = new THREE.Points(particleGeometry, particleMaterial);
122
- scene.add(particles);
 
 
 
123
  }
124
 
125
- function createObstacle() {
126
- const types = ['box', 'sphere', 'cylinder'];
127
  const type = types[Math.floor(Math.random() * types.length)];
128
- let geometry;
129
 
130
- switch(type) {
131
- case 'sphere':
132
- geometry = new THREE.SphereGeometry(0.5);
133
- break;
134
- case 'cylinder':
135
- geometry = new THREE.CylinderGeometry(0.4, 0.4, 1);
136
- break;
137
- default:
138
- geometry = new THREE.BoxGeometry(0.8, 0.8, 0.8);
139
- }
 
 
 
 
 
 
 
140
 
141
- const material = new THREE.MeshPhongMaterial({
142
- color: 0xff0066,
143
- emissive: 0xff0066,
144
- emissiveIntensity: 0.3
145
- });
146
- const obstacle = new THREE.Mesh(geometry, material);
147
- obstacle.position.set(15, type === 'cylinder' ? 0.5 : 0.4, 0);
148
- obstacle.rotation.y = Math.random() * Math.PI;
149
- scene.add(obstacle);
150
- obstacles.push(obstacle);
 
 
 
 
 
 
151
  }
152
 
153
  function createPowerUp() {
154
- if(Math.random() > 0.3) return;
 
155
 
156
- const geometry = new THREE.TetrahedronGeometry(0.4);
157
  const material = new THREE.MeshPhongMaterial({
158
- color: 0xffff00,
159
- emissive: 0xffff00,
160
- emissiveIntensity: 0.5
161
  });
 
162
  const powerUp = new THREE.Mesh(geometry, material);
163
- powerUp.position.set(15, 1.5, Math.random() * 4 - 2);
 
 
 
 
 
 
164
  scene.add(powerUp);
165
  powerUps.push(powerUp);
166
  }
167
 
 
 
 
 
 
168
  function checkCollision(obj) {
169
- const playerBox = new THREE.Box3().expandByObject(player);
170
- const objBox = new THREE.Box3().expandByObject(obj);
171
- return playerBox.intersectsBox(objBox);
 
 
 
 
 
 
172
  }
173
 
174
  function gameOver() {
175
- document.getElementById('restart').style.display = 'block';
176
- config.SPEED = 0;
 
177
  }
178
 
179
  function resetGame() {
180
- obstacles.forEach(o => scene.remove(o));
181
  powerUps.forEach(p => scene.remove(p));
182
- obstacles = [];
183
  powerUps = [];
 
 
 
184
  score = 0;
185
  combo = 1;
186
- config.SPEED = 0.4;
187
- player.position.set(0, 2, 0);
188
- document.getElementById('restart').style.display = 'none';
189
- updateUI();
190
- }
191
-
192
- function updateUI() {
193
- document.getElementById('score').textContent = score;
194
- document.getElementById('combo').textContent = `x${combo}`;
195
  }
196
 
197
  document.addEventListener('keydown', e => {
198
- if(e.code === 'Space' && player.position.y <= 2.1 && config.SPEED > 0) {
199
- velocity = config.JUMP_FORCE;
200
- combo++;
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  }
202
  });
203
 
204
- document.addEventListener('pointerdown', () => {
205
- if(player.position.y <= 2.1 && config.SPEED > 0) {
206
- velocity = config.JUMP_FORCE;
207
- combo++;
 
208
  }
209
  });
210
 
211
- document.getElementById('restart').addEventListener('click', resetGame);
212
 
213
  function animate() {
214
  requestAnimationFrame(animate);
215
 
216
- // Player physics
217
- velocity -= config.GRAVITY;
218
- player.position.y += velocity;
219
- if(player.position.y < 2) {
220
- player.position.y = 2;
221
- velocity = 0;
222
- combo = 1;
223
- }
224
-
225
- // Movement system
226
- obstacles.forEach((obstacle, i) => {
227
- obstacle.position.x -= config.SPEED;
228
- obstacle.rotation.y += 0.05;
229
-
230
- if(obstacle.position.x < -15) {
231
- scene.remove(obstacle);
232
- obstacles.splice(i, 1);
233
- }
234
 
235
- if(checkCollision(obstacle)) gameOver();
236
- });
237
 
238
- powerUps.forEach((powerUp, i) => {
239
- powerUp.position.x -= config.SPEED;
240
- powerUp.rotation.x += 0.1;
241
- powerUp.rotation.y += 0.1;
242
-
243
- if(checkCollision(powerUp)) {
244
- score += 50 * combo;
245
- scene.remove(powerUp);
246
- powerUps.splice(i, 1);
247
- updateUI();
248
- }
249
- });
250
 
251
- // Particle animation
252
- particles.rotation.y += 0.002;
253
-
254
- // Camera follow
255
- camera.position.x += (player.position.x - camera.position.x) * 0.05;
256
- camera.position.z = 7 + (score * 0.0002);
257
-
258
- renderer.render(scene, camera);
259
- }
 
 
 
260
 
261
- // Game loop
262
- setInterval(() => {
263
- if(config.SPEED > 0) {
264
- score += combo;
265
- config.SPEED *= 1.0002;
266
- updateUI();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  }
268
- }, 100);
269
 
270
- setInterval(() => config.SPEED > 0 && createObstacle(), 1500);
271
- setInterval(() => config.SPEED > 0 && createPowerUp(), 3000);
 
 
 
 
 
 
 
 
272
 
273
- // Init
274
  window.addEventListener('resize', () => {
275
  camera.aspect = window.innerWidth / window.innerHeight;
276
  camera.updateProjectionMatrix();
277
  renderer.setSize(window.innerWidth, window.innerHeight);
 
278
  });
279
 
280
  init();
 
1
  <!DOCTYPE html>
2
  <html>
3
  <head>
4
+ <title>Nexus Havoc</title>
5
  <style>
6
+ body { margin: 0; overflow: hidden; }
7
+ #hud {
8
  position: fixed;
9
  top: 20px;
10
+ left: 20px;
11
+ color: #00ff88;
12
+ font-family: 'Orbitron', sans-serif;
13
+ font-size: 18px;
14
+ text-shadow: 0 0 10px #00ff88;
 
 
15
  }
16
+ #gameOver {
17
+ display: none;
18
  position: fixed;
19
  top: 50%;
20
  left: 50%;
21
  transform: translate(-50%, -50%);
22
+ color: #ff0066;
23
+ font-size: 3em;
24
+ text-align: center;
25
+ text-shadow: 0 0 20px #ff0066;
 
 
 
 
26
  }
27
  </style>
28
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500&display=swap" rel="stylesheet">
29
  </head>
30
  <body>
31
+ <div id="hud">
32
+ <div>SPEED: <span id="speed">0</span></div>
33
+ <div>SHIELD: <span id="shield">■</span></div>
34
  <div>SCORE: <span id="score">0</span></div>
35
  <div>COMBO: <span id="combo">x1</span></div>
36
  </div>
37
+ <div id="gameOver">
38
+ <div>SYSTEM FAILURE</div>
39
+ <div style="font-size: 0.5em">CLICK TO REBOOT</div>
40
+ </div>
41
 
42
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
43
+ <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/postprocessing/EffectComposer.js"></script>
44
+ <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/postprocessing/RenderPass.js"></script>
45
+ <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/postprocessing/UnrealBloomPass.js"></script>
46
+ <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/postprocessing/GlitchPass.js"></script>
47
+
48
  <script>
49
+ let scene, camera, renderer, composer, ship;
50
+ let asteroids = [];
51
  let powerUps = [];
52
+ let moveVector = new THREE.Vector3();
53
+ let currentSpeed = 0;
54
+ let shields = 100;
55
  let score = 0;
56
  let combo = 1;
57
+ let lastDodgeTime = 0;
58
+ let gameActive = true;
59
+ let bossActive = false;
60
+
61
  const config = {
62
+ MAX_SPEED: 1.2,
63
+ ACCELERATION: 0.0015,
64
+ ROT_SPEED: 0.04,
65
+ ASTEROID_SPAWN_RATE: 800,
66
+ BLOOM_PARAMS: { strength: 0.6, radius: 0.8, threshold: 0.4 }
67
  };
68
 
69
+ class ParticleTrail {
70
+ constructor() {
71
+ this.particles = [];
72
+ this.geometry = new THREE.BufferGeometry();
73
+ this.material = new THREE.PointsMaterial({
74
+ size: 0.3,
75
+ color: 0x00ff88,
76
+ transparent: true,
77
+ blending: THREE.AdditiveBlending
78
+ });
79
+
80
+ const positions = [];
81
+ for(let i = 0; i < 50; i++) {
82
+ positions.push(0, 0, 0);
83
+ }
84
+ this.geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
85
+ this.points = new THREE.Points(this.geometry, this.material);
86
+ scene.add(this.points);
87
+ }
88
+
89
+ update(shipPos) {
90
+ const positions = this.geometry.attributes.position.array;
91
+ for(let i = positions.length - 3; i >= 3; i -= 3) {
92
+ positions[i] = positions[i - 3];
93
+ positions[i + 1] = positions[i - 2];
94
+ positions[i + 2] = positions[i - 1];
95
+ }
96
+ positions[0] = shipPos.x;
97
+ positions[1] = shipPos.y;
98
+ positions[2] = shipPos.z - 1;
99
+ this.geometry.attributes.position.needsUpdate = true;
100
+ }
101
+ }
102
+
103
  function init() {
104
  scene = new THREE.Scene();
105
  camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
 
108
  renderer.setClearColor(0x000000);
109
  document.body.appendChild(renderer.domElement);
110
 
111
+ // Post-processing
112
+ composer = new THREE.EffectComposer(renderer);
113
+ composer.addPass(new THREE.RenderPass(scene, camera));
114
+
115
+ const bloomPass = new THREE.UnrealBloomPass(
116
+ new THREE.Vector2(window.innerWidth, window.innerHeight),
117
+ config.BLOOM_PARAMS.strength,
118
+ config.BLOOM_PARAMS.radius,
119
+ config.BLOOM_PARAMS.threshold
120
+ );
121
+ composer.addPass(bloomPass);
122
+
123
+ const glitchPass = new THREE.GlitchPass();
124
+ glitchPass.goWild = false;
125
+ composer.addPass(glitchPass);
126
+
127
  // Lighting
128
+ const ambientLight = new THREE.AmbientLight(0x003300);
129
  scene.add(ambientLight);
130
+
131
+ const directionalLight = new THREE.DirectionalLight(0x00ff88, 0.8);
132
+ directionalLight.position.set(0, 10, 10);
133
  scene.add(directionalLight);
134
 
135
+ // Ship
136
+ const geometry = new THREE.ConeGeometry(0.6, 2, 8);
137
+ const material = new THREE.MeshPhongMaterial({
138
+ color: 0x00ff88,
139
+ emissive: 0x005500,
140
+ shininess: 100,
141
+ normalScale: new THREE.Vector2(0.5, 0.5)
142
  });
143
+ ship = new THREE.Mesh(geometry, material);
144
+ ship.rotation.x = Math.PI / 2;
145
+ scene.add(ship);
146
 
147
+ // Engine Trail
148
+ const trail = new ParticleTrail();
 
 
 
 
 
149
 
150
+ // Starfield
151
+ const starsGeometry = new THREE.BufferGeometry();
152
+ const starPositions = [];
153
+ for(let i = 0; i < 10000; i++) {
154
+ starPositions.push(
155
+ (Math.random() - 0.5) * 2000,
156
+ (Math.random() - 0.5) * 2000,
157
+ (Math.random() - 0.5) * 2000
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  );
159
  }
160
+ starsGeometry.setAttribute('position', new THREE.Float32BufferAttribute(starPositions, 3));
161
+ const starsMaterial = new THREE.PointsMaterial({
162
  size: 0.1,
163
+ color: 0xFFFFFF,
164
  transparent: true,
165
+ opacity: 0.8
166
  });
167
+ const stars = new THREE.Points(starsGeometry, starsMaterial);
168
+ scene.add(stars);
169
+
170
+ camera.position.z = 5;
171
+ camera.position.y = 2;
172
  }
173
 
174
+ function createAsteroid() {
175
+ const types = ['normal', 'ice', 'explosive'];
176
  const type = types[Math.floor(Math.random() * types.length)];
177
+ const geometry = new THREE.IcosahedronGeometry(Math.random() * 1.2 + 0.8);
178
 
179
+ const materials = {
180
+ normal: new THREE.MeshPhongMaterial({
181
+ color: 0x606060,
182
+ emissive: 0x202020,
183
+ shininess: 50
184
+ }),
185
+ ice: new THREE.MeshPhongMaterial({
186
+ color: 0x00ffff,
187
+ emissive: 0x004444,
188
+ transparent: true,
189
+ opacity: 0.8
190
+ }),
191
+ explosive: new THREE.MeshPhongMaterial({
192
+ color: 0xff3300,
193
+ emissive: 0x551100
194
+ })
195
+ };
196
 
197
+ const asteroid = new THREE.Mesh(geometry, materials[type]);
198
+ asteroid.position.set(
199
+ Math.random() * 40 - 20,
200
+ Math.random() * 40 - 20,
201
+ -100
202
+ );
203
+
204
+ asteroid.velocity = new THREE.Vector3(
205
+ 0,
206
+ 0,
207
+ Math.random() * 0.8 + currentSpeed
208
+ );
209
+
210
+ asteroid.userData = { type };
211
+ scene.add(asteroid);
212
+ asteroids.push(asteroid);
213
  }
214
 
215
  function createPowerUp() {
216
+ const types = ['shield', 'speed', 'weapon'];
217
+ const type = types[Math.floor(Math.random() * types.length)];
218
 
219
+ const geometry = new THREE.TorusKnotGeometry(0.4, 0.1, 64, 16);
220
  const material = new THREE.MeshPhongMaterial({
221
+ color: type === 'shield' ? 0x0000ff : type === 'speed' ? 0x00ff00 : 0xff00ff,
222
+ emissive: type === 'shield' ? 0x000044 : type === 'speed' ? 0x004400 : 0x440044
 
223
  });
224
+
225
  const powerUp = new THREE.Mesh(geometry, material);
226
+ powerUp.position.set(
227
+ Math.random() * 40 - 20,
228
+ Math.random() * 40 - 20,
229
+ -100
230
+ );
231
+ powerUp.velocity = new THREE.Vector3(0, 0, currentSpeed);
232
+ powerUp.userData = { type };
233
  scene.add(powerUp);
234
  powerUps.push(powerUp);
235
  }
236
 
237
+ function spawnBoss() {
238
+ bossActive = true;
239
+ // Boss implementation would go here
240
+ }
241
+
242
  function checkCollision(obj) {
243
+ const distance = ship.position.distanceTo(obj.position);
244
+ return distance < (obj.userData.type === 'ice' ? 2 : 1.8);
245
+ }
246
+
247
+ function updateHUD() {
248
+ document.getElementById('speed').textContent = Math.floor(currentSpeed * 800);
249
+ document.getElementById('shield').textContent = '■'.repeat(Math.ceil(shields/20));
250
+ document.getElementById('score').textContent = score;
251
+ document.getElementById('combo').textContent = `x${combo}`;
252
  }
253
 
254
  function gameOver() {
255
+ gameActive = false;
256
+ composer.passes[2].goWild = true;
257
+ document.getElementById('gameOver').style.display = 'block';
258
  }
259
 
260
  function resetGame() {
261
+ asteroids.forEach(a => scene.remove(a));
262
  powerUps.forEach(p => scene.remove(p));
263
+ asteroids = [];
264
  powerUps = [];
265
+ ship.position.set(0, 0, 0);
266
+ currentSpeed = 0;
267
+ shields = 100;
268
  score = 0;
269
  combo = 1;
270
+ gameActive = true;
271
+ bossActive = false;
272
+ composer.passes[2].goWild = false;
273
+ document.getElementById('gameOver').style.display = 'none';
 
 
 
 
 
274
  }
275
 
276
  document.addEventListener('keydown', e => {
277
+ if(!gameActive) return;
278
+
279
+ switch(e.key) {
280
+ case 'ArrowUp': moveVector.y = 1; break;
281
+ case 'ArrowDown': moveVector.y = -1; break;
282
+ case 'ArrowLeft': moveVector.x = -1; break;
283
+ case 'ArrowRight': moveVector.x = 1; break;
284
+ }
285
+ });
286
+
287
+ document.addEventListener('keyup', e => {
288
+ switch(e.key) {
289
+ case 'ArrowUp':
290
+ case 'ArrowDown': moveVector.y = 0; break;
291
+ case 'ArrowLeft':
292
+ case 'ArrowRight': moveVector.x = 0; break;
293
  }
294
  });
295
 
296
+ document.addEventListener('mousemove', e => {
297
+ if(gameActive) {
298
+ const rect = renderer.domElement.getBoundingClientRect();
299
+ moveVector.x = (e.clientX - rect.left) / rect.width * 2 - 1;
300
+ moveVector.y = -((e.clientY - rect.top) / rect.height * 2 - 1);
301
  }
302
  });
303
 
304
+ document.addEventListener('click', resetGame);
305
 
306
  function animate() {
307
  requestAnimationFrame(animate);
308
 
309
+ if(gameActive) {
310
+ // Ship movement with inertia
311
+ ship.position.x += (moveVector.x * 8 - ship.position.x) * 0.05;
312
+ ship.position.y += (moveVector.y * 4 - ship.position.y) * 0.05;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
 
314
+ // Progressive difficulty
315
+ currentSpeed = Math.min(config.MAX_SPEED, currentSpeed + config.ACCELERATION);
316
 
317
+ // Combo system
318
+ if(Date.now() - lastDodgeTime > 3000) combo = 1;
 
 
 
 
 
 
 
 
 
 
319
 
320
+ // Asteroid handling
321
+ asteroids.forEach((asteroid, index) => {
322
+ asteroid.position.z += asteroid.velocity.z;
323
+ asteroid.rotation.x += 0.015;
324
+ asteroid.rotation.y += 0.015;
325
+
326
+ if(asteroid.position.z > 20) {
327
+ scene.remove(asteroid);
328
+ asteroids.splice(index, 1);
329
+ score += 10 * combo;
330
+ lastDodgeTime = Date.now();
331
+ }
332
 
333
+ if(checkCollision(asteroid)) {
334
+ if(asteroid.userData.type === 'ice') {
335
+ currentSpeed *= 0.5;
336
+ } else if(asteroid.userData.type === 'explosive') {
337
+ shields -= 30;
338
+ } else {
339
+ shields -= 15;
340
+ }
341
+
342
+ scene.remove(asteroid);
343
+ asteroids.splice(index, 1);
344
+
345
+ if(shields <= 0) gameOver();
346
+ }
347
+ });
348
+
349
+ // PowerUp handling
350
+ powerUps.forEach((powerUp, index) => {
351
+ powerUp.position.z += currentSpeed;
352
+ powerUp.rotation.x += 0.04;
353
+ powerUp.rotation.y += 0.04;
354
+
355
+ if(checkCollision(powerUp)) {
356
+ switch(powerUp.userData.type) {
357
+ case 'shield':
358
+ shields = Math.min(100, shields + 40);
359
+ break;
360
+ case 'speed':
361
+ currentSpeed = Math.min(config.MAX_SPEED + 0.3, currentSpeed + 0.2);
362
+ break;
363
+ }
364
+ scene.remove(powerUp);
365
+ powerUps.splice(index, 1);
366
+ }
367
+ });
368
+
369
+ // Boss encounter
370
+ if(!bossActive && score > 5000) spawnBoss();
371
+
372
+ // Dynamic camera
373
+ const cameraOffset = new THREE.Vector3(
374
+ ship.position.x * 0.5,
375
+ ship.position.y * 0.3 + 3,
376
+ 5 + currentSpeed * 2
377
+ );
378
+ camera.position.lerp(cameraOffset, 0.1);
379
+ camera.lookAt(ship.position);
380
  }
 
381
 
382
+ // Post-processing
383
+ composer.passes[1].strength = currentSpeed * 0.3;
384
+ composer.render();
385
+
386
+ updateHUD();
387
+ }
388
+
389
+ // Game events
390
+ setInterval(() => gameActive && createAsteroid(), config.ASTEROID_SPAWN_RATE);
391
+ setInterval(() => gameActive && createPowerUp(), 2500);
392
 
393
+ // Initialization
394
  window.addEventListener('resize', () => {
395
  camera.aspect = window.innerWidth / window.innerHeight;
396
  camera.updateProjectionMatrix();
397
  renderer.setSize(window.innerWidth, window.innerHeight);
398
+ composer.setSize(window.innerWidth, window.innerHeight);
399
  });
400
 
401
  init();