@@ -3,6 +3,7 @@ import { patterns } from './patterns/formationPatterns.js';
33import SplineCurve from './math/SplineCurve.js' ;
44import BezierPath from './math/BezierPath.js' ;
55import AlienLaser from './LaserParticle.js' ;
6+ import ExplosionEffect from './effects/ExplosionEffect.js' ;
67
78class PatternFormation {
89 constructor ( ctx , options = { } ) {
@@ -17,7 +18,7 @@ class PatternFormation {
1718 patternType : 'infinity' ,
1819 loopDuration : 10 ,
1920 alienCount : 5 ,
20- showPath : true ,
21+ showPath : false , // Changed from true to false
2122 pathPoints : 100 , // number of points to draw on path
2223 formationRadius : 150 , // New separate radius for formation
2324 pulseIntensity : 0 , // Add pulse intensity control
@@ -38,6 +39,9 @@ class PatternFormation {
3839 this . velocity = { x : 0 , y : 0 } ;
3940
4041 this . calculateFormationParameters ( ) ;
42+
43+ // Add tracking of original positions
44+ this . alienSlots = [ ] ; // Keep track of original formation slots
4145 this . createFormation ( ) ;
4246
4347 this . patternNames = Object . keys ( patterns ) ;
@@ -62,6 +66,14 @@ class PatternFormation {
6266
6367 // Delay GUI setup to ensure dat.GUI is loaded
6468 setTimeout ( ( ) => this . setupGUI ( ) , 100 ) ;
69+
70+ this . difficulty = options . difficulty || 1 ;
71+ this . shootInterval = Math . max ( 0.3 , 1.0 - ( this . difficulty * 0.1 ) ) ; // Shoot faster with higher difficulty
72+ this . config . speed = Math . min ( 2.0 , 0.3 + ( this . difficulty * 0.1 ) ) ; // Move faster with higher difficulty
73+ this . initialAlienCount = this . config . alienCount ; // Store initial count
74+ this . pointsBase = 100 ; // Base points per alien
75+
76+ this . explosionEffect = new ExplosionEffect ( ctx ) ;
6577 }
6678
6779 setupGUI ( ) {
@@ -147,23 +159,32 @@ class PatternFormation {
147159 }
148160
149161 createFormation ( ) {
150- this . aliens = [ ] ; // Clear existing aliens
162+ this . aliens = [ ] ;
163+ this . alienSlots = [ ] ; // Reset slots
151164 const count = Math . floor ( this . config . alienCount ) ;
152165
166+ // First, create all possible slots
167+ const angleStep = ( Math . PI * 2 ) / count ;
168+ for ( let i = 0 ; i < count ; i ++ ) {
169+ this . alienSlots . push ( {
170+ index : i ,
171+ angle : i * angleStep ,
172+ occupied : true
173+ } ) ;
174+ }
175+
176+ // Then create aliens and assign them to slots
153177 for ( let i = 0 ; i < count ; i ++ ) {
154178 const alien = new Alien ( this . ctx , {
155179 virtualWidth : this . virtualWidth ,
156180 virtualHeight : this . virtualHeight ,
157- width : 100 , // Explicit size
181+ width : 100 ,
158182 height : 100
159183 } ) ;
160- // Start aliens off-screen at the top
161- alien . x = this . virtualWidth / 2 ;
162- alien . y = - 100 ;
184+ alien . slotIndex = i ; // Remember which slot this alien belongs to
163185 this . aliens . push ( alien ) ;
164186 }
165187
166- // Recalculate formation parameters for new count
167188 this . calculateFormationParameters ( ) ;
168189 }
169190
@@ -234,13 +255,12 @@ class PatternFormation {
234255 ( this . config . pulseIntensity * 5 ) ;
235256 const currentRadius = this . config . formationRadius + pulseAmount ;
236257
237- // Position aliens in formation with pulsing radius
238- const angleStep = ( Math . PI * 2 ) / this . aliens . length ;
239- this . aliens . forEach ( ( alien , index ) => {
240- const formationAngle = index * angleStep ;
258+ // Position aliens in formation based on their slots
259+ this . aliens . forEach ( alien => {
260+ const slot = this . alienSlots [ alien . slotIndex ] ;
261+ const formationAngle = slot . angle ;
241262 const rotationOffset = Math . atan2 ( this . velocity . y , this . velocity . x ) ;
242263
243- // Use pulsing radius
244264 const targetX = pos . x + Math . cos ( formationAngle + rotationOffset ) * currentRadius ;
245265 const targetY = pos . y + Math . sin ( formationAngle + rotationOffset ) * currentRadius ;
246266
@@ -271,6 +291,8 @@ class PatternFormation {
271291 // Update lasers
272292 this . lasers = this . lasers . filter ( laser => laser . life > 0 ) ;
273293 this . lasers . forEach ( laser => laser . update ( delta ) ) ;
294+
295+ this . explosionEffect . update ( delta ) ;
274296 }
275297
276298 shoot ( ) {
@@ -325,6 +347,8 @@ class PatternFormation {
325347
326348 // Draw lasers
327349 this . lasers . forEach ( laser => laser . draw ( this . ctx ) ) ;
350+
351+ this . explosionEffect . draw ( ) ;
328352 }
329353
330354 drawPath ( ) {
@@ -336,7 +360,27 @@ class PatternFormation {
336360 checkCollision ( x , y ) {
337361 for ( let alien of this . aliens ) {
338362 if ( alien . collidesWith ( x , y ) ) {
363+ // Create explosion at alien's center
364+ this . explosionEffect . createExplosion (
365+ alien . x + alien . width / 2 ,
366+ alien . y + alien . height / 2
367+ ) ;
368+
369+ // Mark the slot as unoccupied but don't remove it
370+ this . alienSlots [ alien . slotIndex ] . occupied = false ;
371+
372+ // Remove only this alien
339373 this . aliens = this . aliens . filter ( a => a !== alien ) ;
374+
375+ // Calculate points with multiplier
376+ const pointsMultiplier = this . difficulty * ( 1 + ( this . initialAlienCount - this . aliens . length ) * 0.1 ) ;
377+ const points = Math . floor ( this . pointsBase * pointsMultiplier ) ;
378+
379+ // Add points to game score using window.game
380+ if ( window . game ) {
381+ console . log ( 'Alien destroyed, adding points:' , points ) ; // Debug log
382+ window . game . addPoints ( points ) ;
383+ }
340384 return true ;
341385 }
342386 }
0 commit comments