Thursday, September 26, 2013

LibGDX Tutorial 11: Using Audio

Objectives
  • Using Table to organize the UI
  • Using Array to hold many items
  • Playing Sound and Music

Using sfxr
sfxr (http://drpetter.se/project_sfxr.html) is an audio tool that can be used to make simple game sounds. Starting this program gives





Using the left hand menu I generated 9 different sounds. I named them according to the menu name. The website describe how they generate the frequencies and envelopes and their basis: sine, square, triangle, sawtooth. After saving the files as .wav (lower right corner), I can put them in the assets folder. I also put in one mp3 file. The Sounds are of short duration (few seconds) and music could be in the several minutes range.

Program
The program uses Table to organize the buttons as you can see from the comments. I also use Array and the button code is moved to an external function. For the audio, I have a separate class. I can only only access its methods as they are public and additionally they are static since it would be useless to use a new operator for the Audio.

MyButtonStage2D.java
package com.tutorials.mybuttonstage2d;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.utils.Array;
import com.tutorials.mybuttonstage2d.Sounds.MySound;

public class MyButtonStage2D implements ApplicationListener {
    private OrthographicCamera camera;
    private SpriteBatch batch;
    private Stage stage; //** stage holds the buttons **//
    private BitmapFont font; //** same as that used in Tut 7 **//
    private TextureAtlas buttonsAtlas; //** image of buttons **//
    private Skin buttonSkin; //** images are used as skins of the button **//
    private Array<TextButton> buttons; //** will contain the 9 buttons **//
    private Table table; //** add table to layout UI **//
    float width, height;
   
    @Override
    public void create() {       
        width = Gdx.graphics.getWidth();
        height = Gdx.graphics.getHeight();
       
        camera = new OrthographicCamera();
        camera.setToOrtho(false, width, height);
       
        batch = new SpriteBatch();
       
        buttonsAtlas = new TextureAtlas("buttons.pack"); //** button atlas image **//
        buttonSkin = new Skin();
        buttonSkin.addRegions(buttonsAtlas); //** skins for on and off **//
        font = new BitmapFont(Gdx.files.internal("CustomFont.fnt"),false); //** font **//
       
        stage = new Stage(width, height, true);        //** window is stage **//
        stage.clear();
        Gdx.input.setInputProcessor(stage); //** stage is responsive **//
       
        table = new Table();
        table.setFillParent(true);
       
        buttons = new Array<TextButton>();
        SetButtons(); //** This method is responsible for creating the buttons and listeners **//
       
        for (int i=0; i<9; i++) {
            table.add(buttons.get(i)).space(50).width(250);
            if ((i==2) || (i==5)) table.row();
        }
       
        MySound.PlayMusic(0.5f); //** Volume passed in **//

        /* Above Loop will do these steps
        able.add(buttons.get(0)).space(50).width(250);
        table.add(buttons.get(1)).space(50).width(250);
        table.add(buttons.get(2)).space(50).width(250).row();
        table.add(buttons.get(3)).space(50).width(250);
        table.add(buttons.get(4)).space(50).width(250);
        table.add(buttons.get(5)).space(50).width(250).row();
        table.add(buttons.get(6)).space(50).width(250);
        table.add(buttons.get(7)).space(50).width(250);
        table.add(buttons.get(8)).space(50).width(250);
        */
       
        stage.addActor(table);
    }
   
    private void SetButtons() {
       
        TextButtonStyle style = new TextButtonStyle(); //** Button properties **//
        style.up = buttonSkin.getDrawable("ButtonOff");
        style.down = buttonSkin.getDrawable("ButtonOn");
        style.font = font;
        TextButton button1 = new TextButton("COIN",style);
        buttons.add(button1);
        TextButton button2 = new TextButton("EXPLOSION", style);
        buttons.add(button2);
        TextButton button3 = new TextButton("HIT",style);
        buttons.add(button3);
        TextButton button4 = new TextButton("JUMP",style);
        buttons.add(button4);
        TextButton button5 = new TextButton("POWERUP",style);
        buttons.add(button5);
        TextButton button6 = new TextButton("RANDOMIZE",style);
        buttons.add(button6);
        TextButton button7 = new TextButton("SELECT",style);
        buttons.add(button7);
        TextButton button8 = new TextButton("SHOOT", style);
        buttons.add(button8);
        TextButton button9 = new TextButton("MUTATE", style);
        buttons.add(button9);
        buttons.get(0).addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Coin Pressed");
                    MySound.PlayCoin();
                    return true;
            }
            public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Coin Released");
            }
        });
        buttons.get(1).addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Explosion Pressed");
                    MySound.PlayExplosion();
                    return true;
            }
            public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Explosion Released");
            }
        });
        buttons.get(2).addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Hit Pressed");
                    MySound.PlayHit();
                    return true;
            }
            public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Hit Released");
            }
        });
       
        buttons.get(3).addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Jump Pressed");
                    MySound.PlayJump();
                    return true;
            }
            public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Jump Released");
            }
        });
        buttons.get(4).addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Power Up Pressed");
                    MySound.PlayPowerup();
                    return true;
            }
            public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Power Up Released");
            }
        });
        buttons.get(5).addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Randomize Pressed");
                    MySound.PlayRandomize();
                    return true;
            }
            public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Randomize Released");
            }
        });
        buttons.get(6).addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
                    MySound.PlaySelect();
                    Gdx.app.log("my app", "Select Pressed");
                    return true;
            }
            public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Select Released");
            }
        });
        buttons.get(7).addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Shoot Pressed");
                    MySound.PlayShoot();
                    return true;
            }
            public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Shoot Released");
            }
        });
        buttons.get(8).addListener(new InputListener() {
            public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Mutate Pressed");
                    MySound.PlayMutate();
                    return true;
            }
            public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
                    Gdx.app.log("my app", "Mutate Released");
            }
        });
    }

    @Override
    public void dispose() {
        batch.dispose();
        buttonSkin.dispose();
        buttonsAtlas.dispose();
        font.dispose();
        stage.dispose();
        MySound.DestroyAudio();
    }

    @Override
    public void render() {       
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
       
        stage.act();
       
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        stage.draw();
        batch.end();
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}


MySounds.java
package com.tutorials.mybuttonstage2d.Sounds;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;

public class MySound {
    private static Sound coin = Gdx.audio.newSound(Gdx.files.internal("sounds/coin.wav"));
    private static Sound explosion = Gdx.audio.newSound(Gdx.files.internal("sounds/explosion.wav"));
    private static Sound hit = Gdx.audio.newSound(Gdx.files.internal("sounds/hit.wav"));
    private static Sound jump = Gdx.audio.newSound(Gdx.files.internal("sounds/jump.wav"));
    private static Sound mutate = Gdx.audio.newSound(Gdx.files.internal("sounds/mutate.wav"));
    private static Sound powerup = Gdx.audio.newSound(Gdx.files.internal("sounds/powerup.wav"));
    private static Sound randomize = Gdx.audio.newSound(Gdx.files.internal("sounds/randomize.wav"));
    private static Sound select = Gdx.audio.newSound(Gdx.files.internal("sounds/select.wav"));
    private static Sound shoot = Gdx.audio.newSound(Gdx.files.internal("sounds/shoot.wav"));
    public static Music song = Gdx.audio.newMusic(Gdx.files.internal("sounds/DavidHasselhoff.mp3"));
   
    public static void PlayMusic(float volume){
        song.setLooping(true);
        song.setVolume(volume);
        song.play();
    }
   
    public static void PlayShoot(){
        shoot.play();
    }
   
    public static void PlayMutate(){
        mutate.play();
    }
   
    public static void PlaySelect(){
        select.play();
    }
   
    public static void PlayCoin(){
        coin.play();
    }
   
    public static void PlayExplosion(){
        explosion.play();
    }
   
    public static void PlayHit(){
        hit.play();
    }
   
    public static void PlayJump(){
        jump.play();
    }
   
    public static void PlayPowerup(){
        powerup.play();
    }
   
    public static void PlayRandomize(){
        randomize.play();
    }
   
    public static void DestroyAudio(){
        coin.dispose();
        explosion.dispose();
        hit.dispose();
        jump.dispose();
        mutate.dispose();
        powerup.dispose();
        randomize.dispose();
        select.dispose();
        shoot.dispose();
        song.stop();
        song.dispose();
    }

}


The output when the COIN button is selected:



No comments:

Post a Comment