@@ -153,4 +153,123 @@ export class CombatManager {
153
153
console . log ( `[CombatManager] Handling remote projectile hit: ${ JSON . stringify ( data ) } ` ) ;
154
154
// TODO: Implement remote projectile hit
155
155
}
156
+
157
+ public createRemoteProjectile (
158
+ id : string ,
159
+ position : THREE . Vector3 ,
160
+ velocity : THREE . Vector3 ,
161
+ damage : number ,
162
+ ownerId : string
163
+ ) : void {
164
+ console . log ( `[CombatManager] Creating remote projectile with ID: ${ id } ` ) ;
165
+
166
+ // Find the owner player by ID
167
+ const ownerPlayer = this . players . get ( ownerId ) ;
168
+
169
+ if ( ! ownerPlayer ) {
170
+ console . warn ( `[CombatManager] Owner player with ID ${ ownerId } not found, cannot create projectile` ) ;
171
+ return ;
172
+ }
173
+
174
+ // Create a new projectile with the given parameters
175
+ const projectile = new Projectile (
176
+ position ,
177
+ velocity ,
178
+ damage ,
179
+ ownerPlayer ,
180
+ this . scene ,
181
+ this . world ,
182
+ this . networkManager
183
+ ) ;
184
+
185
+ // Add the projectile to the manager
186
+ this . addProjectile ( projectile ) ;
187
+ }
188
+
189
+ public createImpactEffect ( position : THREE . Vector3 , hitPlayer : boolean ) : void {
190
+ console . log ( `[CombatManager] Creating impact effect at ${ position . x } , ${ position . y } , ${ position . z } ` ) ;
191
+
192
+ // Create a particle effect at the impact position
193
+ const particleCount = hitPlayer ? 20 : 10 ;
194
+ const particleGeometry = new THREE . BufferGeometry ( ) ;
195
+ const particleMaterial = new THREE . PointsMaterial ( {
196
+ color : hitPlayer ? 0xff0000 : 0xcccccc ,
197
+ size : 0.05 ,
198
+ transparent : true ,
199
+ opacity : 0.8
200
+ } ) ;
201
+
202
+ const positions = new Float32Array ( particleCount * 3 ) ;
203
+ const velocities : THREE . Vector3 [ ] = [ ] ;
204
+
205
+ // Initialize particles in a sphere
206
+ for ( let i = 0 ; i < particleCount ; i ++ ) {
207
+ const i3 = i * 3 ;
208
+ positions [ i3 ] = position . x ;
209
+ positions [ i3 + 1 ] = position . y ;
210
+ positions [ i3 + 2 ] = position . z ;
211
+
212
+ // Random velocity direction
213
+ const velocity = new THREE . Vector3 (
214
+ ( Math . random ( ) - 0.5 ) * 2 ,
215
+ ( Math . random ( ) - 0.5 ) * 2 ,
216
+ ( Math . random ( ) - 0.5 ) * 2
217
+ ) . normalize ( ) . multiplyScalar ( 0.1 + Math . random ( ) * 0.2 ) ;
218
+
219
+ velocities . push ( velocity ) ;
220
+ }
221
+
222
+ particleGeometry . setAttribute ( 'position' , new THREE . BufferAttribute ( positions , 3 ) ) ;
223
+
224
+ const particles = new THREE . Points ( particleGeometry , particleMaterial ) ;
225
+ this . scene . add ( particles ) ;
226
+
227
+ // Animate particles
228
+ const startTime = Date . now ( ) ;
229
+ const duration = 500 ; // 500ms
230
+
231
+ const animateParticles = ( ) => {
232
+ const elapsed = Date . now ( ) - startTime ;
233
+ const progress = elapsed / duration ;
234
+
235
+ if ( progress >= 1 ) {
236
+ // Remove particles when animation is complete
237
+ this . scene . remove ( particles ) ;
238
+ return ;
239
+ }
240
+
241
+ // Update particle positions
242
+ const positions = particleGeometry . attributes . position . array as Float32Array ;
243
+
244
+ for ( let i = 0 ; i < particleCount ; i ++ ) {
245
+ const i3 = i * 3 ;
246
+ positions [ i3 ] += velocities [ i ] . x ;
247
+ positions [ i3 + 1 ] += velocities [ i ] . y ;
248
+ positions [ i3 + 2 ] += velocities [ i ] . z ;
249
+
250
+ // Apply gravity
251
+ velocities [ i ] . y -= 0.01 ;
252
+ }
253
+
254
+ particleGeometry . attributes . position . needsUpdate = true ;
255
+
256
+ // Fade out
257
+ particleMaterial . opacity = 0.8 * ( 1 - progress ) ;
258
+
259
+ // Continue animation
260
+ requestAnimationFrame ( animateParticles ) ;
261
+ } ;
262
+
263
+ // Start animation
264
+ animateParticles ( ) ;
265
+
266
+ // Play impact sound
267
+ this . playImpactSound ( hitPlayer ) ;
268
+ }
269
+
270
+ private playImpactSound ( hitPlayer : boolean ) : void {
271
+ const sound = new Audio ( hitPlayer ? '/sounds/hit_impact.mp3' : '/sounds/bullet_impact.mp3' ) ;
272
+ sound . volume = 0.2 ;
273
+ sound . play ( ) . catch ( e => console . error ( "Error playing impact sound:" , e ) ) ;
274
+ }
156
275
}
0 commit comments