Chapter 7 — Sounds and Music / Глава 7 – Звуки и музыка

Chapter 7 — Sounds and Music / Глава 7 - Звуки и музыка

Звуковые эффекты и фоновая музыка являются важной частью игровой опыт. Правильное использование этих важных компонентов может превратить скучную игру в захватывающем приключении!

Предварительная загрузка и потоковое

Есть два способа загрузки аудио в вашем приложении. Какой из них вы используете, как правило, зависит от того, как будет использоваться звуковой файл.

Предзагрузка

Первый способ заключается в использовании audio.loadSound()команды. Это загружает и предварительно обрабатывает весь звуковой файл, после чего он может быть воспроизведен по первому требованию. Например:

local explosionSound = audio.loadSound( "explosion.wav" )

После загрузки, звук может воспроизводиться столько раз , сколько необходимо , используя audio.play()команду вместе с аудио ручку , созданную с помощью audio.loadSound().

Это очень важный аспект , чтобы понять - вы не играть звуковой файл, непосредственно указав имя файла. Вместо того, чтобы указать дескриптор переменной , назначенный audio.loadSound(), в данном случаеexplosionSound.

Например, если наша игра имеет четыре объекта взрываются одновременно , и каждый требует explosion.wavзвук будет играть, мы могли бы выдавать команды:

audio.play( explosionSound )
audio.play( explosionSound )
audio.play( explosionSound )
audio.play( explosionSound )

Другими словами, нет никакой необходимости в предварительной загрузке каких - либо один звуковой файл несколько раз с помощью audio.loadSound() - на explosion.wavзвук будет играть несколько раз, и каждый экземпляр будет присвоен отдельной звуковой канал по умолчанию. Затем, когда экземпляр закончит играть, аудиосистема выпустит / очистить канал так , чтобы другой звук можно воспроизводить на нем.

audio.loadSound()Метод очень удобен, но при загрузке больших аудио файлы или большое количество звуковых файлов в той же точке в вашем приложении, может быть заметная пауза / пропуск , как они загружаются. Таким образом, если вам необходимо загрузить большой звуковой файл в вашем приложении, например , как дорожку фоновой музыки, то, как правило , лучше использовать потоковый метод обсуждается в следующем разделе.

Потоковое

Второй метод для загрузки аудио в ваше приложение с audio.loadStream(). Это будет постепенно загружать и обрабатывать небольшие куски аудиофайла по мере необходимости. Эта команда лучше всего использовать в техслучаях , когда это возможно задержка не будет иметь критическое влияние на удобство использования приложения. Streaming не использует столько памяти, так что , как правило , лучший выбор для больших аудио файлов ,таких как фоновая музыка.

local backgroundMusic = audio.loadStream( "musicTrack1.wav" )
Заметка

В отличие audio.loadSound(), аудио - файлы , загруженные audio.loadStream()могут воспроизводиться только на одном канале , в то время. Если по какой - то причине вам нужно один и тот же звуковой файл для потоковой передачи по нескольким каналам, вам необходимо загрузить два различных аудио ручки, например:

local backgroundMusic1 = audio.loadStream( "musicTrack1.wav" )
local backgroundMusic2 = audio.loadStream( "musicTrack1.wav" )

 

Добавление звуковых эффектов

В том числе аудио файлов

Давайте добавим звуковые эффекты к нашей игре! Во- первых, вам необходимо скачать образцы аудио - файлы, доступные в исходных файлах этой главы здесь . В audioподкаталоге, вы найдете следующие звуковые файлы:

файл Применение
Escape_Looping.wav Музыка для сцены меню.
explosion.wav Шумовой эффект, когда астероид ударил.
fire.wav Шумовой эффект, когда корабль стреляет лазером.
80s-Space-Game_Looping.wav Главный саундтрек для игры.
Midnight-Crawlers_Looping.wav Музыка для высоких результатов сцены.

Для этого проекта, скопировать всю audioвложенную папку и все ее содержимое в вашу StarExplorerпапку проекта. Если вы планируете использовать множество аудио файлов в игре, часто бывает полезно , чтобы держать их организованными в подпапках , как это.

Заметка

Как вы строите игры, вы будете нуждаться звуковые эффекты, музыку, и, возможно, инструмент для редактирования файлов. Вот некоторые ресурсы, чтобы вы начали:

Загрузка Звуки

Во- первых, нам нужно загрузить звуки. Так как наши звуковые эффекты только будет происходить во время игры, мы можем загрузить их в game.luaВ. Сцены доступной области кода, где вы уже заранее объявлены некоторые переменные, добавьте следующие ссылки вперед:

local explosionSound
local fireSound

Затем найдите scene:create()функцию и, вблизи дна непосредственно перед его endстроки, добавьте следующие команды:

explosionSound = audio.loadSound( "audio/explosion.wav" )
fireSound = audio.loadSound( "audio/fire.wav" )

Теперь, когда сцена первой загрузке, звуковые файлы будут загружены в переменную ручками explosionSoundи fireSound. Обратите внимание , что вместо того , чтобы указать только имя файла, мы добавляем его , audio/потому что наши аудио файлы расположены внутри audioвложенной папки.

Воспроизведение звуков

С загружены звуки, теперь мы можем играть их audio.play()всякий раз , когда они необходимы. Взрыв будет воспроизводиться всякий раз , когда лазер попадает астероид или астероид попадает на корабль. Оба этих случаях обнаруживаются onCollision()функции, поэтому мы добавим audio.play( explosionSound )команду в этих двух местах:

  1. В первом условного блока, следуя display.remove()командам, снимающие лазер и астероид.
  2. Во втором условного блока, после died = trueкоманды.
local function onCollision( event )

    if ( event.phase == "began" ) then

        local obj1 = event.object1
        local obj2 = event.object2

        if ( ( obj1.myName == "laser" and obj2.myName == "asteroid" ) or
             ( obj1.myName == "asteroid" and obj2.myName == "laser" ) )
        then
            -- Remove both the laser and asteroid
            display.remove( obj1 )
            display.remove( obj2 )

            -- Play explosion sound!
            audio.play( explosionSound )

            for i = #asteroidsTable, 1, -1 do
                if ( asteroidsTable[i] == obj1 or asteroidsTable[i] == obj2 ) then
                    table.remove( asteroidsTable, i )
                    break
                end
            end

            -- Increase score
            score = score + 100
            scoreText.text = "Score: " .. score

        elseif ( ( obj1.myName == "ship" and obj2.myName == "asteroid" ) or
                 ( obj1.myName == "asteroid" and obj2.myName == "ship" ) )
        then
            if ( died == false ) then
                died = true

                -- Play explosion sound!
                audio.play( explosionSound )

                -- Update lives
                lives = lives - 1
                livesText.text = "Lives: " .. lives

                if ( lives == 0 ) then
                    display.remove( ship )
                    timer.performWithDelay( 2000, endGame )
                else
                    ship.alpha = 0
                    timer.performWithDelay( 1000, restoreShip )
                end
            end
        end
    end
end

И, наконец, нам нужно добавить звуковой эффект для стрельбы лазеров. В начале fireLaser()функции добавьте audio.play( fireSound )команду:

local function fireLaser()

    -- Play fire sound!
    audio.play( fireSound )

    local newLaser = display.newImageRect( mainGroup, objectSheet, 5, 14, 40 )
    physics.addBody( newLaser, "dynamic", { isSensor=true } )
    newLaser.isBullet = true
    newLaser.myName = "laser"

    newLaser.x = ship.x
    newLaser.y = ship.y
    newLaser:toBack()

    transition.to( newLaser, { y=-40, time=500,
        onComplete = function() display.remove( newLaser ) end
    } )
end
Действие!

Теперь у нас есть звуковые эффекты в нашей игре! Сохраните измененный game.luaфайл , а затем повторно запустить Simulator. Играть в игру , и вы должны услышать и звук , когда вы стреляете лазеры и звук взрыва ,когда астероиды хит.

 

Добавление фоновой музыки

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

Загрузка музыки

Как уже говорилось выше, фон музыкальные файлы имеют тенденцию быть большими, так что лучше использовать audio.loadStream(). Во- первых, тем не менее, давайте добавим ссылку вперед для нашей музыкальной дорожки, похожие на звуковые эффекты. В сюжетном доступной области кода , game.luaгде вы уже объявили два вперед ссылки на ваши звуки, добавьте следующую строку:

local musicTrack

Теперь, ближе к концу этого scene:create()функции , в которой вы назвали , audio.loadSound()чтобы загрузить оба звуковые эффекты, добавить новую команду , чтобы начать потоковое музыку на musicTrackпеременной ,которую только что объявили:

    musicTrack = audio.loadStream( "audio/80s-Space-Game_Looping.wav")

Воспроизведение музыки

Теперь пришло время , чтобы играть музыку! На этот раз мы будем шаг глубже в аудио с управления каналом . В принципе, для наших звуковых эффектов, мы просто позволить аудиобиблиотеки выбрать свободный канал , на котором играть любой новый экземпляр звука. Для музыки Тем не менее, часто бывает полезно резервировать определенный канал и играть все фоновой музыки на этом канале - в конце концов, это маловероятно , что вы будете хотеть иметь несколько музыкальных файлов , играющих одновременно, накладываясь друг на друга. Резервируя один выделенный канал для музыки, мы можем использовать его для всех фоновой музыки напротяжении всей игры.

Для достижения этой цели , мы должны обеспечить немного больше информации для нашей audio.play()команды для музыки, а также сделать небольшую дополнительную работу в рамках подготовки для использования выделенного канала.

Во- первых, чтобы зарезервировать канал для музыки на протяжении всей игры, мы можем добавить простую команду в main.luaфайл. Откройте этот файл в выбранном редакторе и, перед composer.gotoScene( "menu" )командой, добавьте следующую строку :

-- Reserve channel 1 for background music
audio.reserveChannels( 1 )

Эта команда просто сообщает фонотеку Corona на резервный канал 1. В то время как зарезервировано, не звуковой файл не будет воспроизводиться на канале , если мы явно не командовать ему.

Теперь, давайте сократить общий объем канала 1. Иногда это необходимо , когда вы получаете аудио файлов из сторонних источников , где вы не имеете никакого контроля объема образца. Она также может быть полезно для управления громкостью каналов , если вы хотите , чтобы позже встроить функциональность , которая позволяет контролировать пользователю уровень громкости игровой музыки, или даже отключить его полностью.

Ниже строки, которые вы только что написали, включают в себя следующее:

-- Reduce the overall volume of the channel
audio.setVolume( 0.5, { channel=1 } )

В сущности , это говорит аудиосистему для воспроизведения любого звукового файла на канале 1в объеме 50% ( 0.5) . Вы можете настроить это в вашей игре , если вы чувствуете , что музыка является либо слишком громко или слишком тихо по отношению к звуковых эффектов.

Теперь, сохранить main.luaи вернуться game.luaв редакторе. Мы начнем играть музыку , когда сцена идет полностью на экране, так что в "did"фазовом состоянии scene:show()функции, добавьте audio.play()команду , так что функция выглядит следующим образом :

function scene:show( event )

    local sceneGroup = self.view
    local phase = event.phase

    if ( phase == "will" ) then
        -- Code here runs when the scene is still off screen (but is about to come on screen)

    elseif ( phase == "did" ) then
        -- Code here runs when the scene is entirely on screen
        physics.start()
        Runtime:addEventListener( "collision", onCollision )
        gameLoopTimer = timer.performWithDelay( 500, gameLoop, 0 )
        -- Start the music!
        audio.play( musicTrack, { channel=1, loops=-1 } )
    end
end

Эта команда просто начинает играть музыку. Это похоже на то, как мы играем звуковые эффекты , за исключением , что она включает в себя таблицу Lua в качестве второго аргумента , содержащего опции команды. В частности, channel=1предписывает фонотеку явно проигрывать музыку на канале 1и loops=-1сообщает аудиосистему повторить (цикл) файл на неопределенный срок.

Действие!

Эти дополнения должны получить воспроизведение музыки в вашем приложении. Убедитесь , что вы сохраните измененные main.luaи game.luaфайлы , а затем повторно запустить Simulator. Играть в игру и теперь вы должны услышать перекручивание музыкальную дорожку в дополнение к звуковых эффектов.

Остановка музыки

В отличие от звуковых эффектов , которые , как правило , короткие и получают очищенную от их канала после завершения, потоковой музыки обычно должна быть остановлена в соответствующее время , когда вы собираетесь покинуть сцену. Это может быть легко обработаны в "did"фазовом состоянии scene:hide()функции. Найдите этот блок внутри game.luaи добавьте audio.stop( 1 )команду , так что функция выглядит следующим образом :

function scene:hide( event )

    local sceneGroup = self.view
    local phase = event.phase

    if ( phase == "will" ) then
        -- Code here runs when the scene is on screen (but is about to go off screen)
        timer.cancel( gameLoopTimer )

    elseif ( phase == "did" ) then
        -- Code here runs immediately after the scene goes entirely off screen
        Runtime:removeEventListener( "collision", onCollision )
        physics.pause()
        -- Stop the music!
        audio.stop( 1 )
    end
end

Это оно! Когда сцена полностью выходит за кадром, музыка играет на канале 1остановится, расчистив путь для другой музыкальный трек , чтобы играть на канале в следующей сцене.

 

Располагая Аудио

Если предварительно загружены или потоковое, аудио занимает память , и это ресурс , который не автоматически управляются или очищаются с помощью Composer. В результате, есть один последний важный шаг в этой главе:  утилизации аудио . Это где scene:destroy()функция пригодится, так как он сработал в результате вызова composer.removeScene () или когда сам композитор разрушает сцену.

В вашем game.luaфайле, найдите scene:destroy()функцию вблизи дна. Внутри него, добавить три audio.dispose()команды , как показано здесь:

function scene:destroy( event )

    local sceneGroup = self.view
    -- Code here runs prior to the removal of scene's view
    -- Dispose audio!
    audio.dispose( explosionSound )
    audio.dispose( fireSound )
    audio.dispose( musicTrack )
end

Используя эти команды, мы эффективно освободить память, занимаемую аудиофайле.

Аналогично audio.play(), обратите внимание , что мы поставляем аудио ручку к audio.dispose()команде, например explosionSound. Вы должны не пытаться избавиться аудио, указав имя звукового файла.

 

Дополнительный кредит

Несмотря на то, что мы сделали это для вас в этой главе в исходных файлах , бросить вызов себе реализовать музыку в двух других сцен, используя те же приемы и аудио сцены концепции событий , которые мы , описанные выше!

Место действия Музыка Файл
menu.lua Escape_Looping.wav
highscores.lua Midnight-Crawlers_Looping.wav

 

Глава Концепции

Мы рассмотрели несколько концепций в этой главе, все они связаны с аудио:

Команда / Недвижимость Описание
audio.loadSound () Загружает весь файл полностью в память и возвращает ссылку на аудиоданных.
audio.loadStream () Грузы (открывает) файл для чтения, как потоковое аудио.
audio.reserveChannels () Резервы определенное количество каналов, поэтому они не будут автоматически назначены играть.
audio.setVolume () Устанавливает громкость либо для конкретного канала, или задает общий уровень громкости.
audio.play () Воспроизведение аудио, заданный звуковой ручкой на канале.
audio.stop () Остановка воспроизведения на канале (или всех каналов) и очищает канал (ы) , чтобы они могли быть воспроизведены снова.
audio.dispose () Релизы аудио память, связанная с ручкой.

YoGo
Language