@@ -247,6 +247,86 @@ <h1>PlyGround Physics Engine</h1>
247247 spawnedBodies = spawnedBodies . filter ( b => b !== e . body ) ;
248248 }
249249} ) ;
250+ // --- Spacebar Explosion + Delayed Shockwave ---
251+ document . addEventListener ( "keydown" , e => {
252+ if ( e . code === "Space" ) {
253+ const x = mouse . position . x ;
254+ const y = mouse . position . y ;
255+
256+ // 💣 Spawn explosive cube (TNT)
257+ const bomb = Bodies . rectangle ( x , y , 50 , 50 , {
258+ restitution : 0.8 ,
259+ frictionAir : 0.02 ,
260+ render : { fillStyle : "#ff3333" }
261+ } ) ;
262+ World . add ( world , bomb ) ;
263+ spawnedBodies . push ( bomb ) ;
264+
265+ // 💥 Wait, then detonate at TNT's actual position
266+ setTimeout ( ( ) => {
267+ const bx = bomb . position . x ;
268+ const by = bomb . position . y ;
269+
270+ const blastRadius = 300 ;
271+ const blastPower = 0.25 ;
272+
273+ spawnedBodies . forEach ( body => {
274+ if ( body !== bomb && ! body . isStatic ) {
275+ const dir = Vector . sub ( body . position , { x : bx , y : by } ) ;
276+ const dist = Vector . magnitude ( dir ) ;
277+
278+ if ( dist < blastRadius ) {
279+ const normalized = Vector . normalise ( dir ) ;
280+ const falloff = 1 - dist / blastRadius ;
281+ const force = Vector . mult ( normalized , blastPower * falloff ) ;
282+ Body . applyForce ( body , body . position , force ) ;
283+ }
284+ }
285+ } ) ;
286+
287+ // 💣 Remove bomb after blast
288+ World . remove ( world , bomb ) ;
289+ spawnedBodies = spawnedBodies . filter ( b => b !== bomb ) ;
290+
291+ // 🌊 Create shockwave AFTER explosion
292+ setTimeout ( ( ) => {
293+ const ring = {
294+ x : bx ,
295+ y : by ,
296+ radius : 0 ,
297+ opacity : 1
298+ } ;
299+ shockwaves . push ( ring ) ;
300+ } , 200 ) ; // delay for realistic timing
301+
302+ } , 800 ) ; // detonation delay
303+ }
304+ } ) ;
305+
306+ // 🌀 Animate shockwave rings
307+ const shockwaves = [ ] ;
308+
309+ ( function animateShockwaves ( ) {
310+ requestAnimationFrame ( animateShockwaves ) ;
311+ const ctx = render . context ;
312+
313+ shockwaves . forEach ( ( r , i ) => {
314+ r . radius += 6 ; // expansion speed
315+ r . opacity -= 0.02 ; // fade out speed
316+
317+ if ( r . opacity <= 0 ) {
318+ shockwaves . splice ( i , 1 ) ;
319+ return ;
320+ }
321+
322+ ctx . beginPath ( ) ;
323+ ctx . arc ( r . x , r . y , r . radius , 0 , 2 * Math . PI ) ;
324+ ctx . strokeStyle = `rgba(255, 170, 0, ${ r . opacity } )` ; // glowing orange
325+ ctx . lineWidth = 5 ;
326+ ctx . stroke ( ) ;
327+ } ) ;
328+ } ) ( ) ;
329+
250330</ script >
251331</ body >
252332</ html >
0 commit comments