# Ducking

> A home run whose roar takes the music down while it sounds and lets it back up on its own, without touching the options volume.

Example `ducking`, running at https://nacatamalon.com/en/examples/ducking. The whole catalogue: https://nacatamalon.com/llms/examples.md.

A sound with `duck` holds another channel down while it plays: here the roar takes the music to 25% and, once it is over, lets it back up in a second. There is nothing to undo: when the sound ends, is stopped or leaves with its object, the channel comes back up by itself.

It moves a volume of its own behind the channel, so the one `useAudio().setVolume` sets, the options screen's, stays where it was. The crack and the roar are not files: they are effects made from presets, `useSound({ sfx: { preset } })`.

Space for a home run.

## Code

`index.ts`:

```ts
import { createGame } from 'nacatamalon';
import * as Settings from './settings';
import { Ballpark } from './scenes/demo';

const game = createGame('#app', {
    width: Settings.WIDTH,
    height: Settings.HEIGHT,
    background: '#0a1420',
});

// Declare Scenes
game({
    Ballpark,
});
```

`components/homerun.ts`:

```ts
import { createSprite, createText, useAudio, useKeyboard, useLoadBitmapFont, useSound, useUpdate } from 'nacatamalon';
import * as Settings from '../settings';

export const HomeRun = () => {
    const font = useLoadBitmapFont(Settings.ARCADE);
    const keys = useKeyboard();
    const audio = useAudio();

    useSound({
        src: '/example-assets/audio/stage_land.wav'
    }, {
        channel: 'music',
        loop: true,
        autoplay: true
    });
    audio.setVolume(0.8, 'music');

    const crack = useSound({
        sfx: {
            preset: 'hit',
            pitch: 1.4
        }
    }, {
        volume: 0.9
    });

    const roar = useSound({
        sfx: {
            preset: 'explosion',
            length: 3,
            pitch: 0.7,
            seed: 4
        }
    }, {
        channel: 'crowd',
        duck: {
            channel: 'music',
            to: 0.25,
            fade: 0.1,
            release: 1
        },
    });

    createSprite({
        tint: '#2f7a3a',
        width: 480,
        height: 120,
        transform: {
            x: 240,
            y: 260
        }
    });

    const sign = createText({
        text: '',
        font,
        style: {
            fontSize: 24
        },
        tint: Settings.YELLOW,
        anchor: {
            x: 0.5,
            y: 0.5
        },
        transform: {
            x: 240,
            y: 120
        }
    });

    createText({
        text: 'SPACE HOME RUN',
        font,
        style: {
            fontSize: 8
        },
        tint: Settings.WHITE,
        anchor: {
            x: 0.5,
            y: 0
        },
        transform: {
            x: 240,
            y: 286
        }
    });

    useUpdate((_delta, time) => {
        if (keys.justPressed(' ')) {
            crack.play();
            roar.play();
        }

        sign.text = roar.playing ? 'HOME RUN!' : '';
        sign.transform.y = 120 + Math.sin(time * 12) * 3;
    });
};
```

`scenes/demo.ts`:

```ts
import { createScene, useSpawn } from 'nacatamalon';

import { HomeRun } from '../components/homerun';

export const Ballpark = () => {
    useSpawn(HomeRun)();

    return createScene();
};
```

`settings.ts`:

```ts
import { getColor } from 'nacatamalon';

export const WIDTH = 480;
export const HEIGHT = 320;
export const ARCADE = {
    json: '/example-assets/fonts/bitmaps/nacatamal-arcade/nacatamal-arcade.json',
    atlas: '/example-assets/fonts/bitmaps/nacatamal-arcade/nacatamal-arcade.png',
};
export const WHITE = getColor('#ffffff');
export const YELLOW = getColor('#f5c518');
```
