Программирование игр для Windows. Советы профессионала

       

Использование звука в играх


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

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

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

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

Алгоритм 9,1. Псевдокод планировщика звуков.

while(true)

// оценить время поставленных в очередь звуковых эффектов.

// Если звук уже неактуален, удалить его из очереди. Если нет

// исполняемого звукового эффекта, начать воспроизведение




// первого звука в очереди

else

// если запрашиваемый звуковой эффект имеет более высокий

// приоритет, чем текущий звук (например, игрок выстрелил

// из ружья) - прервать текущий звук и начать исполнение



// эффекта с более высоким приоритетом

else

// если запрашиваемый звуковой эффект имеет меньший приоритет,

// чем текущий звук, установить его в очередь

end

Алгоритм 9.1 - весьма хороший черновой пример планировщика. Он позволяет организовать очередь звуков и контролировать их исполнение.

Но все-таки если во время компьютерной игры может раздаваться только один звук в каждый момент времени, это будет слишком скучно. Как же воспроизводить несколько звуков одновременно? Мы можем это сделать с помощью одного трюка.

Представьте, что звук выстрела из лазерного пистолета и звук рычания страшного чудовища должны раздаться одновременно. Предположим также, что у них одинаковый приоритет. По Алгоритму 9.1 мы должны бросить жребий и сыграть их последовательно. Но почему нельзя сложить звуки вместе и получить требуемый результат?

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

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

§

Мы можем просто отсечь звук по границе восьми или шестнадцати бит;

§          Мы можем брать только процентное соотношение волн, что гарантирует попадание их суммы в нужные нам пределы.

Алгоритм 9.2 представляет собой один из вариантов процедуры наложения звуков.

Алгоритм 9.2. Псевдокод наложения звуков.

length one=length (sound one)

length two=length (sound two)

if length one > length two

// обработать первую часть звука



for index== 0 to length two new sound [index] = .5 * sound onetindex]+ .5 * sound two[index]

// обработать оставшуюся часть звука, // просто копируя его с уменьшением for index=length two+1 to length one

new sound [index] =.5 * sound one[index]

else

// обработать первую часть звука

for index=0 to length one

new sound [index] =.5 * sound one[index]+ .5 * sound two[index]

// обработать оставшуюся часть звука,

// просто копируя его с уменьшением

for index= length one+1 to length two

new sound [index] =.5 * sound two[index] end

По сути, Алгоритм 9.2 — это все, что вам нужно для того, чтобы сложить звуки вместе. Конечно, здесь складываются только два звука, но алгоритм легко может быть приведен к более общему виду. Проблема только в том, что вам потребуется больше времени и памяти. Если у вас в память загружены два VOC-файла по 60К, вы должны будете сделать 60000 сложений, на что уйдет несколько миллисекунд. Это вполне терпимо, но результат сложения нужно поместить в новый буфер размером 60К. Так что, будьте осторожны!


Содержание раздела