Evgenii Legotckoi
23 вересня 2015 р. 21:00

Як зробити гру за допомогою Qt - Урок 5. Додавання звуку QMediaPlayer

Приступаємо до п'ятого та заключного уроку з написання гри на Qt, у якому додамо звук за допомогою класу QMediaPlayer . Пропоную додати три види звуків: Поїдання яблук, дзижчання Мухи , яка дзижчатиме при пересуванні і несамовитий крик, коли Муху з'їдять.

Звук у структурі проекту

Звук у структурі проекту міститься у файл ресурсів, як показано на скріншоті структури проекту.

Для цього створюємо папку resource і в ній папку game. Далі в папці resources створюємо файл ресурсів, у якому прописуємо префікс "/" та додаємо аудіо файли, які попередньо помістили до папки game.

А далі звуки необхідно підключити до проекту за допомогою класу QMediaPlayer.

У разі звуки підключаються у трьох місцях програмного коду.


трикутник.h

У заголовному файлі необхідно підключити бібліотеки класів QMediaPlayer та QMediaPlaylist. А також оголосити за об'єктом цих класів.

  1. #ifndef TRIANGLE_H
  2. #define TRIANGLE_H
  3.  
  4. #include <QObject>
  5. #include <QGraphicsItem>
  6. #include <QPainter>
  7. #include <QGraphicsScene>
  8. #include <QMediaPlayer>
  9. #include <QMediaPlaylist>
  10.  
  11. /** Подключаем библиотеку, отвечающую за использование WinAPI
  12. * Данная библиотека необходима для асинхронной проверки состояния клавиш
  13. * */
  14. #include <windows.h>
  15.  
  16. class Triangle : public QObject, public QGraphicsItem
  17. {
  18. Q_OBJECT
  19. public:
  20. explicit Triangle(QObject *parent = 0);
  21. ~Triangle();
  22.  
  23. // Программный код из прошлых уроков
  24.  
  25. QMediaPlayer * m_player; // Аудио плеер
  26. QMediaPlaylist * m_playlist; // Плейлист
  27.  
  28. };
  29.  
  30. #endif // TRIANGLE_H

triangle.cpp

Ініціалізація об'єкта QMediaPlayer буде проводиться в конструкторі класу, але управління програвання звуку буде реалізовано в ігровому слоті Мусі , оскільки Муха повинна дзижчати лише тоді, коли пересувається по ігровій сцені.

  1. #include "triangle.h"
  2.  
  3. Triangle::Triangle(QObject *parent) :
  4. QObject(parent), QGraphicsItem()
  5. {
  6. angle = 0; /// Задаём угол поворота графического объекта
  7. steps = 1; /// Задаём стартовое положение ножек мухи
  8. countForSteps = 0; /// Счётчик для отсчета тиков таймера, при которых мы нажимали на кнопки
  9. setRotation(angle); /// Устанавливаем угол поворота графического объекта
  10.  
  11. m_player = new QMediaPlayer(this); // Инициализация плеера
  12. m_playlist = new QMediaPlaylist(m_player); // Инициализация плейлиста
  13.  
  14. m_player->setPlaylist(m_playlist); // Установка плейлиста в аудио плеер
  15. m_playlist->addMedia(QUrl("qrc:/game/bzzz.wav")); // Добавление трека в плейлист
  16. m_playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop); // Зацикливание трека
  17. }
  18.  
  19. Triangle::~Triangle()
  20. {
  21.  
  22. }
  23.  
  24. QRectF Triangle::boundingRect() const
  25. {
  26. return QRectF(-40,-50,80,100); /// Ограничиваем область, в которой лежит треугольник
  27. }
  28.  
  29. void Triangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
  30. {
  31. // Программный код из прошлых уроков
  32. }
  33.  
  34. void Triangle::slotGameTimer()
  35. {
  36. /* Проверяем, нажата ли была какая-либо из кнопок управления объектом.
  37. * Прежде чем считать шажки
  38. * */
  39. if(GetAsyncKeyState(VK_LEFT) ||
  40. GetAsyncKeyState(VK_RIGHT) ||
  41. GetAsyncKeyState(VK_UP) ||
  42. GetAsyncKeyState(VK_DOWN))
  43. {
  44. // Программный код из прошлых уроков
  45.  
  46. m_player->play(); // Плеер играет только тогда, когда муха движется
  47. } else {
  48. m_player->stop(); // Если Муха не движется, то отключаем плее
  49. }
  50.  
  51. // Программный код из прошлых уроков
  52. }

віджет.h

У заголовному файлі класу, який відіграє роль ядра гри, необхідно лише підключити бібліотеки, які відповідають за класи QMediaPlayer та QMediaPlaylist.

widget.cpp

У цьому класі немає глобального оголошення об'єкта QMediaPlayer, оскільки об'єкти створюються динамічно, наприклад, для кожного з'їденого яблука. Через те, що яблука можуть з'їдатися дуже швидко і практично одночасно, то і звуки поїдання яблук будуть звучати разом, а один плеєр не впорається з таким завданням, тому доведеться запускати по плеєрі на кожен звук. Також окремим плеєром програватиметься загибель Мухи .

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3.  
  4. Widget::Widget(QWidget *parent) :
  5. QWidget(parent),
  6. ui(new Ui::Widget)
  7. {
  8. // программный код из прошлых уроков
  9. }
  10.  
  11. Widget::~Widget()
  12. {
  13. delete ui;
  14. }
  15.  
  16. void Widget::slotDeleteApple(QGraphicsItem *item)
  17. {
  18. /* Получив сигнал от Мухи
  19. * Перебираем весь список яблок и удаляем найденное яблоко
  20. * */
  21. foreach (QGraphicsItem *apple, apples) {
  22. if(apple == item){
  23. scene->removeItem(apple); // Удаляем со сцены
  24. apples.removeOne(apple); // Удаляем из списка
  25. delete apple; // Вообще удаляем
  26. ui->lcdNumber->display(count++); /* Увеличиваем счёт на единицу
  27. * и отображаем на дисплее
  28. * */
  29. // Звук поедания яблока
  30. QMediaPlayer * m_player = new QMediaPlayer(this); // Инициализируем плеер
  31. QMediaPlaylist * m_playlist = new QMediaPlaylist(m_player); // Создаём плейлист
  32.  
  33. m_player->setPlaylist(m_playlist); // Устанавливаем плейлист в плеер
  34. m_playlist->addMedia(QUrl("qrc:/game/hrum.wav")); // Добавляем аудио в плеер
  35. m_playlist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce); // Проигрываем один раз
  36. m_player->play(); // Запускаем плеер
  37. }
  38. }
  39. }
  40.  
  41. void Widget::slotCreateApple()
  42. {
  43. // программный код из прошлых уроков
  44. }
  45.  
  46. void Widget::on_pushButton_clicked()
  47. {
  48. // программный код из прошлых уроков);
  49.  
  50. ui->pushButton->setEnabled(false);
  51.  
  52. gameState = GAME_STARTED;
  53. }
  54.  
  55. void Widget::slotGameOver()
  56. {
  57. /* Если игра окончена
  58. * Отключаем все таймеры
  59. * */
  60. timer->stop();
  61. timerCreateApple->stop();
  62.  
  63. // Если Муха Погибла, то запускаем предсмертный крик
  64. QMediaPlayer * m_player = new QMediaPlayer(this); // Создаём плеер
  65. QMediaPlaylist * m_playlist = new QMediaPlaylist(m_player); // Создаём плейлист
  66.  
  67. m_player->setPlaylist(m_playlist); // Устанавливаем плейлист в плеер
  68. m_playlist->addMedia(QUrl("qrc:/game/scream.wav")); // Добавляем аудио в плейлист
  69. m_playlist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce); // Проигрываем трек один раз
  70. m_player->play(); // Запускаем трек
  71.  
  72. // программный код из прошлых уроков
  73. }
  74.  
  75. void Widget::slotPause()
  76. {
  77. // программный код из прошлых уроков
  78. }

Підсумок

Ось і закінчено роботу над нашою першою грою. Тепер у Вас є уявлення про те, як створити просту гру на Qt C++.

Усі, хто цікавиться вихідниками гри, можуть завантажити їх за цим посиланням: Source

Всі, хто цікавиться самою грою і просто хоче в неї зіграти, можуть завантажити її за цим посиланням: [/Muha_Setup]

Повний список статей цього циклу:

Відеоурок

Вам це подобається? Поділіться в соціальних мережах!

ВН
  • 22 березня 2019 р. 17:08
  • (відредаговано)

Из кьюта приложение не хочет запускаться, аварийно завершается, но каких-либо ошибок не выдаёт. Оно открывается, после нажатия "старт" зависает и завершается. Если не из кьюта запускать дебаг - та же ерунда. Релиз вообще отказывается работать, ошибки на картинках. Все dll и libs доложила и в дебаг, и в релиз. В чём может быть проблема?
А windeployqt вообще динамит, открывает консоль на секунду - и всё. Удаление qmakes и pro.user тоже не помогает


Ну может бибилотеки не те положили? У вас сборка для MinGW, а либы для MSVC.

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
  • Останні коментарі
  • IscanderChe
    12 квітня 2025 р. 17:12
    Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
  • AK
    01 квітня 2025 р. 11:41
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    09 березня 2025 р. 21:02
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    09 березня 2025 р. 16:14
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
  • ИМ
    22 листопада 2024 р. 21:51
    Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…