Music Implementation - UQdeco2800/2021-ext-studio-2 GitHub Wiki

Overview

Design "bgms for every screens & sound effects in the game" is heavily weighed on the design rather than program. However, we still decide to document this part of code. Add the designed musics into the game doesn't need much code. So basically, we don't need any design patterns for this. We collabrate with team 7 and build a new class called BackgroundSoundComponent.java. This handles the audio display clearer.

Code description

UML-Class Diagram

The code implementations for each screen bgm are same so this class diagram demonstrates the "MainMenuScreen" bgm

Code explanation

This is an example of adding bgm into one screen. We changed "ui" as an global variable in this class. So that, the dispose() method can dispose the ui completely. Doing this can make the bgm stops when switch to another screen. Otherise, there will be different bgms playing at the same time.

  @Override
  public void dispose() {
    logger.debug("Disposing main menu screen");

    renderer.dispose();
    unloadAssets();
    ui.dispose();

    ServiceLocator.getRenderService().dispose();
    ServiceLocator.getEntityService().dispose();

    ServiceLocator.clear();
  }

  private void createUI() {
    logger.debug("Creating ui");
    Stage stage = ServiceLocator.getRenderService().getStage();
    //set ui as global variable so that the bgm will be stopped when close the screen
    ui = new Entity();
    ui.addComponent(new MainMenuDisplay())
        .addComponent(new BackgroundSoundComponent("sounds/mainmenu_bgm.mp3", 0.5f))
        .addComponent(new InputDecorator(stage, 10))
        .addComponent(new MainMenuActions(game));
    ServiceLocator.getEntityService().register(ui);
  }

This class handles the musics loading and unloading as well as the volume and loop or not.

public class BackgroundSoundComponent extends Component {

    private final String backgroundMusic;
    private final float volume;
    private final boolean looping;

    /**
     * @param backgroundMusic the background music path
     */
    public BackgroundSoundComponent(String backgroundMusic) {
        this.backgroundMusic = backgroundMusic;
        this.volume = 0.3f;
        this.looping = true;
        loadSound();
    }

    /**
     * @param backgroundMusic the background music path
     * @param volume the volume to be set
     */
    public BackgroundSoundComponent(String backgroundMusic, float volume) {
        this.backgroundMusic = backgroundMusic;
        this.volume = volume;
        this.looping = true;
        loadSound();
    }

    /**
     * @param backgroundMusic set the background music
     * @param volume set the volume
     * @param looping set the looping to true or false
     */
    public BackgroundSoundComponent(String backgroundMusic, float volume, boolean looping) {
        this.backgroundMusic = backgroundMusic;
        this.volume = volume;
        this.looping = looping;
        loadSound();
    }

    /**
     * Load the background music
     */
    private void loadSound() {
        ResourceService resourceService = ServiceLocator.getResourceService();
        resourceService.loadMusic(new String[]{backgroundMusic});
        resourceService.loadAll();
    }

    @Override
    public void create() {
        super.create();
        playSound();
    }

    /**
     * Play the background music
     */
    public void playSound() {
        Music music = ServiceLocator.getResourceService().getAsset(backgroundMusic, Music.class);
        music.setLooping(looping);
        music.setVolume(volume);
        music.play();
    }

    @Override
    public void dispose() {
        stopSound();

        unloadSound();
        super.dispose();
    }

    /**
     * Stop playing the music
     */
    public void stopSound() {
        ServiceLocator.getResourceService().getAsset(backgroundMusic, Music.class).stop();
    }

    /**
     * Dispose background music
     */
    private void unloadSound() {
        ServiceLocator.getResourceService().unloadAssets(new String[]{backgroundMusic});
    }