- 1. Звук в структуре проекта
- 2. triangle.h
- 3. triangle.cpp
- 4. widget.h
- 5. widget.cpp
- 6. Итог
- 7. Видеоурок
Приступаем к пятому и заключительному уроку по написанию игры на Qt, в котором добавим звук с помощью класса QMediaPlayer . Предлагаю добавить три вида звуков: Поедание яблок, жужжание Мухи , которая будет жужжать при передвижении и душераздирающий вопль, когда Муху съедят.
Звук в структуре проекта
Звук в структуре проекта помещается в файл ресурсов, как показано на скриншоте структуры проекта.
Для этого создаём папку resource и в ней папку game. Далее в папке resources создаём файл ресурсов, в котором прописываем префикс "/" и добавляем аудио файлы, которые предварительно поместили в папку game.
А далее звуки необходимо подключить к проекту с использованием класса QMediaPlayer.
В данном случае звуки подключаются в трёх местах программного кода.
triangle.h
В заголовочном файле необходимо подключить библиотеки классов QMediaPlayer и QMediaPlaylist. А также объявить по объекту этих классов.
#ifndef TRIANGLE_H #define TRIANGLE_H #include <QObject> #include <QGraphicsItem> #include <QPainter> #include <QGraphicsScene> #include <QMediaPlayer> #include <QMediaPlaylist> /** Подключаем библиотеку, отвечающую за использование WinAPI * Данная библиотека необходима для асинхронной проверки состояния клавиш * */ #include <windows.h> class Triangle : public QObject, public QGraphicsItem { Q_OBJECT public: explicit Triangle(QObject *parent = 0); ~Triangle(); // Программный код из прошлых уроков QMediaPlayer * m_player; // Аудио плеер QMediaPlaylist * m_playlist; // Плейлист }; #endif // TRIANGLE_H
triangle.cpp
Инициализация объекта QMediaPlayer будет производится в конструкторе класса, но управление проигрывание звука будет реализовано в игровом слоте Мухе , поскольку Муха должна жужжать только тогда, когда передвигается по игровой сцене.
#include "triangle.h" Triangle::Triangle(QObject *parent) : QObject(parent), QGraphicsItem() { angle = 0; /// Задаём угол поворота графического объекта steps = 1; /// Задаём стартовое положение ножек мухи countForSteps = 0; /// Счётчик для отсчета тиков таймера, при которых мы нажимали на кнопки setRotation(angle); /// Устанавливаем угол поворота графического объекта m_player = new QMediaPlayer(this); // Инициализация плеера m_playlist = new QMediaPlaylist(m_player); // Инициализация плейлиста m_player->setPlaylist(m_playlist); // Установка плейлиста в аудио плеер m_playlist->addMedia(QUrl("qrc:/game/bzzz.wav")); // Добавление трека в плейлист m_playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop); // Зацикливание трека } Triangle::~Triangle() { } QRectF Triangle::boundingRect() const { return QRectF(-40,-50,80,100); /// Ограничиваем область, в которой лежит треугольник } void Triangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { // Программный код из прошлых уроков } void Triangle::slotGameTimer() { /* Проверяем, нажата ли была какая-либо из кнопок управления объектом. * Прежде чем считать шажки * */ if(GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState(VK_UP) || GetAsyncKeyState(VK_DOWN)) { // Программный код из прошлых уроков m_player->play(); // Плеер играет только тогда, когда муха движется } else { m_player->stop(); // Если Муха не движется, то отключаем плее } // Программный код из прошлых уроков }
widget.h
В заголовочном файле класса, который играет роль ядра игры, необходимо только подключить библиотеки, которые отвечают за классы QMediaPlayer и QMediaPlaylist.
widget.cpp
В данном классе нет глобального объявления объекта QMediaPlayer, поскольку объекты создаются динамически, например для каждого съеденного яблока. Из-за того, что яблоки могут съедаться очень быстро и практически одновременно, то и звуки поедания яблок будут звучать вместе, а один плеер не справится с такой задачей, поэтому придётся запускать по плееру на каждый звук. Также отдельным плеером будет проигрываться гибель Мухи .
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { // программный код из прошлых уроков } Widget::~Widget() { delete ui; } void Widget::slotDeleteApple(QGraphicsItem *item) { /* Получив сигнал от Мухи * Перебираем весь список яблок и удаляем найденное яблоко * */ foreach (QGraphicsItem *apple, apples) { if(apple == item){ scene->removeItem(apple); // Удаляем со сцены apples.removeOne(apple); // Удаляем из списка delete apple; // Вообще удаляем ui->lcdNumber->display(count++); /* Увеличиваем счёт на единицу * и отображаем на дисплее * */ // Звук поедания яблока QMediaPlayer * m_player = new QMediaPlayer(this); // Инициализируем плеер QMediaPlaylist * m_playlist = new QMediaPlaylist(m_player); // Создаём плейлист m_player->setPlaylist(m_playlist); // Устанавливаем плейлист в плеер m_playlist->addMedia(QUrl("qrc:/game/hrum.wav")); // Добавляем аудио в плеер m_playlist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce); // Проигрываем один раз m_player->play(); // Запускаем плеер } } } void Widget::slotCreateApple() { // программный код из прошлых уроков } void Widget::on_pushButton_clicked() { // программный код из прошлых уроков); ui->pushButton->setEnabled(false); gameState = GAME_STARTED; } void Widget::slotGameOver() { /* Если игра окончена * Отключаем все таймеры * */ timer->stop(); timerCreateApple->stop(); // Если Муха Погибла, то запускаем предсмертный крик QMediaPlayer * m_player = new QMediaPlayer(this); // Создаём плеер QMediaPlaylist * m_playlist = new QMediaPlaylist(m_player); // Создаём плейлист m_player->setPlaylist(m_playlist); // Устанавливаем плейлист в плеер m_playlist->addMedia(QUrl("qrc:/game/scream.wav")); // Добавляем аудио в плейлист m_playlist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce); // Проигрываем трек один раз m_player->play(); // Запускаем трек // программный код из прошлых уроков } void Widget::slotPause() { // программный код из прошлых уроков }
Итог
Вот и закончена работа над нашей первой игрой. Теперь у Вас имеется представление о том, как создать простенькую игру на Qt C++.
Все, кто интересуется исходниками игры, могут скачать их по этой ссылке: Source
Все, кто интересуется самой игрой и просто хочет в неё сыграть, могут скачать её по этой ссылке: Muha_Setup
Полный список статей данного цикла:
- Урок 1. Как написать игру на Qt. Управление объектом
- Урок 2. Как написать игру на Qt. Анимация героя игры (2D)
- Урок 3. Как написать игру на Qt. Взаимодействие с другими объектами
- Урок 4. Как написать игру на Qt. Враг - смысл в выживании
- Урок 5. Как написать игру на Qt. Добавляем звук с QMediaPlayer
Из кьюта приложение не хочет запускаться, аварийно завершается, но каких-либо ошибок не выдаёт. Оно открывается, после нажатия "старт" зависает и завершается. Если не из кьюта запускать дебаг - та же ерунда. Релиз вообще отказывается работать, ошибки на картинках. Все dll и libs доложила и в дебаг, и в релиз. В чём может быть проблема?
А windeployqt вообще динамит, открывает консоль на секунду - и всё. Удаление qmakes и pro.user тоже не помогает
Ну может бибилотеки не те положили? У вас сборка для MinGW, а либы для MSVC.