Android: использование Audio в libgdx

Озвучку движения игрока сделал. Слегка пришлось повозиться, правда (: Обычно я эмулятор использовал только для игр, но они, как выяснилось, позволяют дебажить игры и вытаскивать из них ресурсы =D

Вообще, первоначальная проблема была в том, что не было у меня звуковых файлов из игры. Пропарсив .nes файлы, кое-что достать удалось, но вот звуки движений не получилось. Думал, как же вытащить или где найти. Оказалось, что эмулька Nestopia позволят писать аудио потоки из игры прям в файл. Ну да, многие эмуляторы это умеют, но в этом можно заглушать некоторые потоки. Заглушил поток фоновой музыки и засейвил звуки движений. Потом, правда, в Audacity подгонять пришлось, чтоб бесшовно звук был.

В итоге, звуки есть, теперь надо их как-то использовать в libgdx. Сразу пришлось в классе Bomberman менять direction. Двигает то он, как правило, только в одном направлении, но вот в оригинальной игре озвучка движения по вертикали и горизонтали отличается. Логично конечно просто запускать обе озвучки, если двигается по двум направлениям сразу, но как оказалось озвучка в оригинальной игре – это не просто запуск двух озвучек, а именно отдельная (:

Собственно, создал массив ауди спрайтов, так сказать, и юзал уже их потом:

//массив аудио дорожек
public Map<String, Sound> sounds = new HashMap<String, Sound>();

//добавляем необходимые дорожки
private void loadSounds(){
  sounds.put("left-right", Gdx.audio.newSound(Gdx.files.internal("audio/left-right.ogg")));
  sounds.put("up-down", Gdx.audio.newSound(Gdx.files.internal("audio/up-down.ogg")));
  sounds.put("double-direction", Gdx.audio.newSound(Gdx.files.internal("audio/double-direction.ogg")));
		
}		

Теперь просто надо в нужный момент проигрывать. При рендеринге сцены вызываю метод:


//играет музло или нет
boolean isPlaying = false;
private void playMusic(){
  Bomberman bomberman = world.getBomberman();
  //есил игрок двигается
  if(bomberman.getState() == Bomberman.State.WALKING){
    //если мызыка не играет
    if(!isPlaying)
    {
      isPlaying = true;
      //если идём по горизонтали и не по вертикали
      if((bomberman.getDirection(Bomberman.Direction.LEFT) || bomberman.getDirection(Bomberman.Direction.RIGHT)) &&!(bomberman.getDirection(Bomberman.Direction.UP) || bomberman.getDirection(Bomberman.Direction.DOWN)))
         //врубаем музло...loop означает, что зациклена мызыка
         //в противоположность play(), который сыграет лишь 1 раз
	 sounds.get("left-right").loop();
          ...
         //дальше по аналогии для движения по вертикали
    }
  }
  //если не движемся
  else{
    //если играет музло
    if(isPlaying){
      //отключаем
      isPlaying = false;
      sounds.get("left-right").stop();
      sounds.get("up-down").stop();
      sounds.get("double-direction").stop();
			
      }
    }
}

Вот и вся магия. И да, ничто не мешает вам одновременно несколько Audio файлов проигрывать: фон и движение. libgdx их в разных потоках крутит, что очень радует. Единственное, что не понимаю, почему нету метода по проверке вроде “isPlaying”. Приходится самому флаги создавать.

UDP: как оказалось, надо просто использовать класс Music вместо Audio. У него как раз есть метод isPlaying(), что позволяет не создавать лишних флагов (:

  Категории: Android, java, libgdx, Игры, Коддинг
  • Алексей

    Спасибо, за статью…. до звука ещё руки не доходят. :)

    Я вот думаю как разделить в два потока рендер и логику приложения, и вобще стоит ли это делать))))
    заманало писать в рендаре абдейт загруски файлов, или апдейт физики..

    • http://suvitruf.ru Suvitruf

      На вкус и цвет,как говорится. Я вообще стараюсь MVC придерживаться. Так что в игре, которую сейчас пишу, логику и рендеринг разграничил, что очень упрощает разработку.

      Всё-таки собираюсь с этой недели начать в бложик выкладывать уроки по libgdx. В каком-нить из них расскажу, как можно разбить проект на составляющие)

  • Avara

    Здравствуйте!
    Сталкивались ли вы с проблемой отключения музыки?

    К примеру у меня беда:

    В проекте, в главном меню, есть пункт “Settings”, в котором есть всего лишь одна кнопка “Sounds”, которая работает как выключатель(т.е. нажал – звук есть, нажал – звука нет) и отключает или включает звук во всей игре. Итак сама проблема заключается в следующем:
    по нажатию возврата в главное меню, а затем снова вход в “settings”, если музыка играет и я нажимаю на кнопку, запускается ещё один экземпляр музыки и играет один и тот же трек в две дорожки.

    программа почему-то думает что isPlaying() == false

    Как решить эту проблему… Заранее спасибо за ответ!

    soundsButton.addListener(new ClickListener(){
    public void clicked(InputEvent event, float x, float y)
    {
    if(global.musicIntro.isPlaying() == true)
    {
    if(global.musicIntro.isPlaying() == true) global.musicIntro.pause();
    else global.musicIntro.play();
    }

    else
    {
    if(global.musicIntro.isPlaying() == false) global.musicIntro.play();
    }

    }
    });

    • http://suvitruf.ru Suvitruf

      Со звуком были проблемы, но такого рода нет.