The community is working on translating this tutorial into Estonian, but it seems that no one has started the translation process for this article yet. If you can help us, then please click "More info".
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!
Improving SnakeWPF: Adding sound
Most games will have sound effects to enhance the experience, but so far, our little snake implementation is completely quiet. We have previously talked about both audio and video in this tutorial, so if you have read these articles, you know that playing a sound with WPF is quite easy. In fact, if you can live with the system sounds, it can be done with a single line of code:
SystemSounds.Beep.Play();
If you need a bit more than that, you can use the MediaPlayer class to play your own audio files (e.g. MP3). You can read all about it in this article: Playing audio with WPF. A fun little project could be to record the sound of you taking a bite of an apple and then playing it when the snake eats an apple - it's quite easy to accomplish!
Making the Snake talk
For this tutorial, I decided to go another way than just playing regular sound bites - I want the Snake to talk! This might sound difficult, but only if you haven't read all the articles in this tutorial, because if you have, you know that WPF has great support for Speech synthesis. With this, we can make the snake talk very easily!
First of all, you need to add a reference to the System.Speech assembly to your project. For specific instructions on adding exactly this assembly to your project, please see this previous article: Speech synthesis (making WPF talk). In the top, you'll find a detailed walk-through of how to accomplish this.
I've decided to make the Snake talk in several situations, so I will create a common SpeechSynthesizer instance which I will re-use each time, but start by adding a reference to the System.Speech.Synthesis namespace in the top:
using System.Speech.Synthesis;
Then declare and initialize the instance at the top of your Window:
public partial class MainWindow : Window
{
private SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer();
.......
"Yummy!"
That's all we need to make the Snake talk - but when should it talk and what should it say? I decided to make it say "yummy" each time it eats an apple. This happens in the EatSnakeFood() method which we implemented previously, so just add a single line in the top of it:
private void EatSnakeFood()
{
speechSynthesizer.SpeakAsync("yummy");
......
That's it - run the game and enjoy the "yummy" each time the snake eats an apple. Of course the text string can be change to another word or even a sentence, if you feel like it.
"Oh no - you died!"
Saying "yummy" is super simple, as you can see, but the SpeechSynthesizer can do a lot more than that! To demonstrate it, I have decided to make the Snake talk about its own death and the final score of the game - in other words, we need to add some talk to the EndGame() method. There will be quite a few lines of extra code, because I want several sentences with different speech settings, so I've decided to encapsulate the end-of-game-talk-code in its own method called SpeakEndOfGameInfo(). It's called at the bottom of the EndGame() method, implemented previously in this tutorial, so just add the call at the bottom of the method:
private void EndGame()
{
.......
SpeakEndOfGameInfo(isNewHighscore);
}
Here's how our implementation of it looks:
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);
}
So that's quite a bit of code, but if you look closer, you'll see that there's a lot of the same stuff - we basically use a PromptBuilder instance to create a longer sentence, with various pronunciation settings. At the end, this will make the Snake say "Oh no - you died" each time you die. If you made it into the high score list, added in one of the previous articles, it will add "New high score:", followed by the actual score.
Each part of this is spoken with appropriate settings, using PromptStyle instances - for instance, "oh no - you died" is spoken slowly, with an increased volume. We also use the AppendBreak() method to add natural breaks between the different parts. You can read more about these techniques in our previous article on the speech synthesis.
Summary
Thanks to the System.Speech assembly and the SpeechSynthesizer class, our Snake has just learned to talk! This makes the game a lot more fun, while demonstrating how cool, powerful and flexible the .NET framework is.