Поиск по этому блогу

четверг, 23 августа 2012 г.

Пишем игру под Android: Часть 8: Фоновая музыка в игре

Эту часть я очень сильно затянул так как не было времени разбираться как проигрывать музыку в фоне. Занимался другими проектами, и до сих пор занимаюсь, так что эту часть я напишу коротко и понятно. Сложного в этой части ничего нету так что все будет быстро и безболезненно (: Предыдущие 7 частей вы можете найти ниже:

  1. Пишем игру под Android: Часть 1 — Рисуем картинки на SurfaceView
  2. Пишем игру под Android: Часть 2 — Создаем первый спрайт
  3. Пишем игру под Android: Часть 3 — Спрайтовая анимация, работа с несколькими спрайтами
  4. Пишем игру под Android: Часть 4 — onTouchEvent и определение столкновений
  5. Пишем игру под Android: Часть 5 — Создание полноценной 2D игры
  6. Пишем игру под Android: Часть 6: Добавление звука
  7. Пишем игру под Android: Часть 7: Меню для игры и окно приветствия
  8. Пишем игру под Android: Часть 8: Фоновая музыка в игре
Давно еще меня просили написать эту статью, еще в февряла этого года, простите те кто просили, что так вышло. И так начнем с самого простого, открываем нашу игру в которой хотим добавить музыку, добавляем в папку res/raw/ наш *.mp3 файл, именно mp3, так как на wav и wma выдает ошибку, и создаем файлMyService.java который будет сервисом для нашего проигрывания музыки. Код он будет содержать в себе следующий:

MyService.java
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class MyService extends Service {
        private static final String TAG = "MyService";
        MediaPlayer player;
        
        @Override
        public IBinder onBind(Intent intent) {
                return null;
        }
        
        @Override
        public void onCreate() {
                Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
                
                player = MediaPlayer.create(this, R.raw.bg);
                player.setLooping(true); // зацикливаем
        }

        @Override
        public void onDestroy() {
                Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
                player.stop();
        }
        
        @Override
        public void onStart(Intent intent, int startid) {
                Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
                player.start();
        }
}

Что мы тут имеем? Ну сперва как видно мы унаследовали наш класс от класса Service для того что бы наш класс мог работать в фоне и ничего нам не мешало только для этого его и юзать. Дальше нам открывается методonCreate() который запускает медиаплеер с файлом который будет проигрываться. После этого идет класс уничтожения (выключения) музыки, когда нам понадобится, например выйти из игры или выключить музыку мы будем обращаться к этому методу для выключения музыки. Ну и onStart() метод который запускает наш сервис что бы музыка начала проигрываться.

Дальше нам нужно сказать еклипсу что этот класс юзается в фоне, и никак не сметь его запускать в виде активности или другой какой-то байды (: Для этого открываем AndroidManifest и вставляем перед закрывающимся :

<service android:enabled="true" android:name=".MyService" />

Ну и конечно же нам нужно вызывать этот класс и наши методы для запуска музыки, если вы хотите что бы музыка начиналась запускаться сразу при входе в игру, то есть сразу из меню, то вам нужно в главной активитиStartActivity.java который запускает наше меню написать в onCreate() вот такое:

StartActivity.java

//import...
public class StartActivity extends Activity implements OnClickListener {          
    public void onCreate(Bundle savedInstanceState) {
        //...
        
        //-------------------------------------------------------------------------------
        startService(new Intent(this, MyService.class)); //вот єто вам нужно написать!!!!!!
        //-------------------------------------------------------------------------------
    }

    /** Обработка нажатия кнопок */
    public void onClick(View v) {
                //...
        }
}

Ну а что бы выключить при выходе из игры или по желанию юзера тогда добавляем метод onBackPressed() и в нем пишем вот такое:

StartActivity.java
private void onBackPressed() {
     stopService(new Intent(this, MyService.class));
}

И тогда у нас сервис остановится, музыка замолчит, и если вы пропишите в этом методе finish() то приложения закроется.

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

13 комментариев:

  1. Хорошие статьи. Действительно помогли в написании первой игры.

    ОтветитьУдалить
  2. А зачем здесь класс сервиса? MediaPlayer и так, что-то вроде адаптера к системному медиа сервису. Бутерброд из колбасы и колбасы получился.

    ОтветитьУдалить
    Ответы
    1. Ну сервис нужен для работы в фоне, я как бы распаралелил работу, попробуйте сделать без сервиса и потом расскажите впечатления (:

      Удалить
    2. Если трек большого размера, то для долгого чтения там есть связка функций
      MediaPlayer.setOnPreparedListener
      и
      MediaPlayer.prepareAsync
      и то, я бы посоветовал посмотреть на решение проблемы уменьшением размера трека, т.к. устройства с андроидом 44кГц с системой 7.1 я ещё не видел например.

      Я понимаю что сервис как пример в документации есть, но такой сервис нужно использовать для другого рода приложений. Т.к. в onCreate вы создаете сервис, который вызывает свой onCreate, а в onDestroy вы его удаляете с вызовом соответствующего onDestroy сервиса, то это и получается масло масленное

      Удалить
  3. Нуу, собственно системный медиа сервис и так работает параллельно, можете убрать player.stop(); в MyService .onDestroy(), запустить длинный трек и выйти из приложения, сервис будет продолжать играть этот трек, вне зависимости от того, работает приложение или нет

    ОтветитьУдалить
  4. большое спасибо за статьи!

    ОтветитьУдалить
  5. как поменять фон на свои обои?

    ОтветитьУдалить
  6. ругается на эту строчку, как сделать так чтобы в файле R он указывал на ресурс
    player = MediaPlayer.create(this, R.raw.bg);

    ОтветитьУдалить
    Ответы
    1. Название своего ресурса написать.. Здесь файл называется bg, у Вас должно быть вписано своё название.

      Удалить
  7. ПАМАГИТЕ у меня музыка теперь всегда играет. что делать?

    ОтветитьУдалить
    Ответы
    1. закрывать приложение в диспетчере задач

      Удалить
    2. В настройках принудительно остановить, или пересобрать проект

      Удалить