Back to Supersonic RC Revive
SOURCE / PINNED RELEASE

Made of little things.

Supersonic RC Revive

Release
1ba42f1ca1d6…
Author-recorded commit
baecad10b1cd…
License
LICENSE
Author’s source reference
nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.napplet.soy%2F/n-143146b0d6f

Archive hash verified: 90d22b206672eba4…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/game/lingo/carSound.ts
// Port of "ParentScript 22 - carsound" plus car.collision's crash sounds.
import type { Input } from '../input.js';
import type { SoundMixer } from '../audio.js';
import type { Car } from './car.js';

const random = (n: number) => 1 + Math.floor(Math.random() * n);

export class CarSound {
  private readonly musicLoops = ['musicloop1', 'musicloop2', 'musicloop3', 'musicloop4', 'musicloop5'];
  private pPlaying = 0;
  private pShift = 1;
  private pStopped = 0;
  private pState: 'left' | 'right' | 'middle' = 'middle';
  private readonly crashUp = ['crash1', 'Crash2', 'crash3', 'crash4', 'crash5', 'crash6', 'crash7', 'crash8'];
  private readonly crashDown = ['Crash1_glass', 'Crash2_glass', 'Crash3_glass'];

  constructor(
    private readonly car: Car,
    private readonly input: Input,
    private readonly mixer: SoundMixer,
    private readonly firstChannel = 1,
    private readonly ownsMusic = true,
  ) {
    mixer.sound(firstChannel).volume = 25;
    mixer.sound(firstChannel + 1).volume = 20;
    if (ownsMusic) {
      const music = mixer.sound(8);
      music.stop();
      music.play({ member: this.musicLoops[random(5) - 1] });
      music.fadeTo(75, 500);
    }
    car.events.crash = (upright) => this.crash(upright);
  }

  /** car.collision: one-shot on channel 3 unless one is still playing; lists rotate. */
  private crash(upright: boolean): void {
    const ch = this.mixer.sound(this.firstChannel + 2);
    if (ch.current) return;
    const list = upright ? this.crashUp : this.crashDown;
    const member = list.shift()!;
    list.push(member);
    ch.play({ member });
    ch.volume = 125;
  }

  /** Per chunk, from car.update. */
  update(): void {
    const s = (n: number) => this.mixer.sound(n === 8 ? 8 : this.firstChannel + n - 1);
    if (this.ownsMusic && s(8).playlistCount() < 3 && !this.pStopped) s(8).queue({ member: this.musicLoops[random(5) - 1] });
    let throttle = false;
    let left = false;
    let right = false;
    if (!this.pStopped) {
      throttle = this.input.keyPressed(126) || this.input.keyPressed(125);
      // A controller stick leaning past halfway turns like an arrow key.
      left = this.input.keyPressed(123) || this.input.steerAxis() <= -0.5;
      right = this.input.keyPressed(124) || this.input.steerAxis() >= 0.5;
    }
    if (throttle && !this.pPlaying) {
      const tStart = this.car.rb.linearVelocity.length() * 4 - 150;
      s(1).play({ member: 'CarStart', rateShift: this.pShift, startTime: Math.max(0, tStart) });
      s(1).queue({ member: 'CarLoop', loopCount: 0, rateShift: this.pShift });
      this.pPlaying = 1;
    } else if (this.pPlaying && !throttle) {
      if (s(1).current === 'carstart') {
        s(1).play({ member: 'carend', startTime: Math.max(0, this.mixer.duration('carend') - s(1).currentTime / 2 - 10) });
      } else {
        s(1).play({ member: 'CarEnd' });
      }
      this.pPlaying = 0;
    }
    if (left && this.pState !== 'left') {
      s(2).play({ member: `carturnleft0${random(3)}` });
      this.pState = 'left';
    } else if (right && this.pState !== 'right') {
      s(2).play({ member: `carturnright0${random(3)}` });
      this.pState = 'right';
    }
    if (!right && !left && this.pState !== 'middle') {
      s(2).play({ member: this.pState === 'left' ? `carturnright0${random(3)}` : `carturnleft0${random(3)}` });
      this.pState = 'middle';
    }
    const w = this.car.wheels;
    let tShift = 2 - (w[0].pOnGround + w[1].pOnGround) * 0.5 + 0.1;
    if (this.car.pReversing) tShift = 0.2;
    if (this.pShift !== tShift && this.pPlaying) s(1).play({ member: 'carloop', loopCount: 0, rateShift: tShift });
    this.pShift = tShift;
  }

  stopDriving(): void {
    this.pStopped = 1;
    if (this.ownsMusic) this.mixer.sound(8).fadeOut(500);
  }

  destroy(): void {
    this.mixer.sound(this.firstChannel).stop();
    this.mixer.sound(this.firstChannel + 1).stop();
    this.mixer.sound(this.firstChannel + 2).stop();
  }
}