Skip to content

Commit 268e39b

Browse files
Copilotjbampton
andauthored
Add invader-hit SFX on bullet collisions in Space Invaders (#443)
* Add hit sound when Space Invaders bullet destroys an invader Agent-Logs-Url: https://github.com/NextCommunity/NextCommunity.github.io/sessions/2e21a107-94cf-4f0c-8d3f-8dae8d66ef0b Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com> * Clean up Web Audio nodes after invader hit sound Agent-Logs-Url: https://github.com/NextCommunity/NextCommunity.github.io/sessions/2e21a107-94cf-4f0c-8d3f-8dae8d66ef0b Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
1 parent bddb285 commit 268e39b

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

src/assets/js/games/space-invaders.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const SpaceInvaders = (() => {
1212
const ALIEN_ROWS = ["👾", "👽", "🛸", "🐙", "👾"];
1313
const GAME_ID = "space-invaders";
1414
const BULLET_CLEANUP_BUFFER = 40;
15+
let _audioContext = null;
1516

1617
// ─── Public entry-point ──────────────────────────────────────────────────
1718

@@ -152,6 +153,7 @@ const SpaceInvaders = (() => {
152153
(bullet, alien) => {
153154
bullet.destroy();
154155
alien.destroy();
156+
_playInvaderHitSound();
155157

156158
if (scene.si_aliens.countActive() === 0) {
157159
_onVictory(scene);
@@ -224,6 +226,40 @@ const SpaceInvaders = (() => {
224226
scene.si_lastFired = now;
225227
}
226228

229+
function _playInvaderHitSound() {
230+
const AudioCtx = window.AudioContext || window.webkitAudioContext;
231+
if (!AudioCtx) return;
232+
233+
if (!_audioContext) {
234+
_audioContext = new AudioCtx();
235+
}
236+
if (_audioContext.state === "suspended") {
237+
_audioContext.resume().catch(() => {});
238+
}
239+
240+
const now = _audioContext.currentTime;
241+
const oscillator = _audioContext.createOscillator();
242+
const gainNode = _audioContext.createGain();
243+
244+
oscillator.type = "square";
245+
oscillator.frequency.setValueAtTime(840, now);
246+
oscillator.frequency.exponentialRampToValueAtTime(280, now + 0.08);
247+
248+
gainNode.gain.setValueAtTime(0.0001, now);
249+
gainNode.gain.exponentialRampToValueAtTime(0.12, now + 0.01);
250+
gainNode.gain.exponentialRampToValueAtTime(0.0001, now + 0.09);
251+
252+
oscillator.connect(gainNode);
253+
gainNode.connect(_audioContext.destination);
254+
oscillator.onended = () => {
255+
oscillator.disconnect();
256+
gainNode.disconnect();
257+
};
258+
259+
oscillator.start(now);
260+
oscillator.stop(now + 0.1);
261+
}
262+
227263
// ─── Victory / cleanup ────────────────────────────────────────────────────
228264

229265
function _onVictory(scene) {

0 commit comments

Comments
 (0)