This article has been localized into Russian by the community.
In this article series, we're building a complete Snake game from scratch. It makes sense to start with the Introduction and then work your way through the articles one by one, to get the full understanding.
If you want to get the complete source code for the game at once, to get started modifying and learning from it right now, consider downloading all our samples!
Улучшаем SnakeWPF: Добавляем звук
Большинство игр использует звуковые эффекты для улучшения восприятия игроком, однако наша маленькая змейка пока хранит молчание. В этом руководстве мы уже говорили о звуке и даже видео, поэтому если вы читали эти главы то знаете, что проигрывание звука в WPF достаточно просто организовать. И даже больше, если вас удовлетворяют системные звуки то они могут быть добавлены всего одной строкой кода:
SystemSounds.Beep.Play();
Если вы хотите больше, чем системные звуки придется использовать класс MediaPlayer для того, чтобы проигрывать собственные аудио файлы (например формата MP3). Здесь вы можете пролучить массу полезной информации на эту тему: Playing audio with WPF. В качестве маленького проекта вы можете записать звук смачного откусывания яблока и проигрывать его в момент, когда смейка съедает яблоко - это просто воплотить!
Учим Змейку говорить
В этом руководстве я решил пойти другим путем, не просто проигрывать звуковые байты - я хочу, чтобы Змейка говорила! Это может звучать как трудная задача, но только если вы не прочли все статьи этого руководства. Потому что если вы прочли их то знате, что в главе Speech synthesis говорилось о речевом синтезаторе. Используя его мы можем легко заставить Змейку говорить!
Первым делом, необходимо добавить ссылку на сборку System.Speech в наш проект. Если вы хотите подробней узнать о том, как это делается обратите внимание на эту статью: Speech synthesis (making WPF talk). В верхней части подробно описано, как это делается.
Я решил сделать так, чтобы Змейка говорила в некоторых определенных ситуациях, поэтому я создам общий экземпляр SpeechSynthesizer, который буду использовать несколько раз, но первым делом добавлю пространство имен System.Speech.Synthesis вверху:
using System.Speech.Synthesis;
А затем объявлю и инициирую экземпляр в верхней части Window:
public partial class MainWindow : Window
{
private SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer();
.......
"Вкусно!"
Это все, что нужно, чтобы наша Змейка заговорила - но когда она должна это делать, и что именно говорить? Я решил, что она должна говорить "Вкусно" каждый раз, когда она съедает яблоко. Это происходит в методе EatSnakeFood(), который мы уже написали, поэтому добавим в него одну единственную строчку:
private void EatSnakeFood()
{
speechSynthesizer.SpeakAsync("yummy");
......
Вот и все - теперь запустите игру и наслаждайтесь тем, как ваша Змейка смачно съедает яблоко и говорит при этом "yummy". Разумеется можно произносимое слово и даже заменить на целое предложение, если вам так нравится.
"О нет - вы умерли!"
Заставить змейку произнести "yummy" оказалось просто, но SpeechSynthesizer может гораздо больше этого! Чтобы продемонстрировать я решил сделать так, чтобы Змейка сообщала о своей собственной смерти и о достигнутом счете. Другими словами нам нужно добавить разговорную часть в метод EndGame(). Будет достаточно много кода т.к. я хочу использовать несколько предложений с разными разговорными настройками. Поэтому я решил инкапсулировать код-слов-конца-игры (end-of-game-talk-code) в свой собственный метод SpeakEndOfGameInfo(). Вызываю этот метод в конце EndGame(), который мы написали ранее. Просто добавьте вызов нашего нового метода в конце:
private void EndGame()
{
.......
SpeakEndOfGameInfo(isNewHighscore);
}
Так выглядит код нового метода:
private void SpeakEndOfGameInfo(bool isNewHighscore)
{
PromptBuilder promptBuilder = new PromptBuilder();
promptBuilder.StartStyle(new PromptStyle()
{
Emphasis = PromptEmphasis.Reduced,
Rate = PromptRate.Slow,
Volume = PromptVolume.ExtraLoud
});
promptBuilder.AppendText("oh no");
promptBuilder.AppendBreak(TimeSpan.FromMilliseconds(200));
promptBuilder.AppendText("you died");
promptBuilder.EndStyle();
if(isNewHighscore)
{
promptBuilder.AppendBreak(TimeSpan.FromMilliseconds(500));
promptBuilder.StartStyle(new PromptStyle()
{
Emphasis = PromptEmphasis.Moderate,
Rate = PromptRate.Medium,
Volume = PromptVolume.Medium
});
promptBuilder.AppendText("new high score:");
promptBuilder.AppendBreak(TimeSpan.FromMilliseconds(200));
promptBuilder.AppendTextWithHint(currentScore.ToString(), SayAs.NumberCardinal);
promptBuilder.EndStyle();
}
speechSynthesizer.SpeakAsync(promptBuilder);
}
Выглядит, как о-о-очень много кода, но если присмотреться то вы увидите, что для того, чтобы создать длинное предложение очень много используется экземпляр PromptBuilder с разными установки произнесения. В это заставит Змейку говорить "О нет - вы умерли" ("Oh no - you died"), каждый раз в конце игры. Если вам удалось попасть в список рекордов, который мы добавили чуть выше, добавится "Новый рекорд" ("New high score:") и затем будет указан собственно счет.
Каждая часть предложения сказано с использованием определенных установок PromptStyle, например "о нет - вы умерли" ("oh no - you died") сказано медленно, с увеличенной громкостью. Мы также используем метод AppendBreak() для того, чтобы добавить естественные разрывы между разными частями. Вы можете подробней прочитать об этом здесь: previous article on the speech synthesis
Обобщая
Благодаря сборке System.Speech и классу SpeechSynthesizer наша Змейка научилась говорить! Это делает игру гораздо занимательней, при этом показывая крутизну и мощь .NET framework.