We will add three sounds. Each sound will be played on a particular game event. A simple thud sound whenever the player chops, a gloomy losing sound when the player runs out of time, and a retro crushing sound when the player is squished to death.
SFML plays sound effects using two different classes. The first class is the SoundBuffer
class. This is the class that holds the actual audio data from the sound file. It is the SoundBuffer
that is responsible for loading the .wav
files into the PC's RAM in a format that can be played without any further decoding work.
In a minute, when we write code for the sound effects, we will see that, once we have a SoundBuffer
object with our sound stored in it, we will then create another object of the type Sound
. We can then associate this Sound
object with a SoundBuffer
object. Then, at the appropriate moment in our code, we will be able to call the play
function of the appropriate Sound
object.
As we will see very soon, the C++ code to load and play sounds is really simple. What we need to consider, however, is when to call the play
function. Where in our code will we put the function calls to play
? Following are some of the features we want to achieve:
if
block that detects that a tree has mangled the playerif
block that detects that the timeRemaining
is less than zeroNow we can write our sound code.
First we add another #include
directive to make the SFML sound-related classes available. Add the following highlighted code:
#include "stdafx.h"
#include <sstream>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
using namespace sf;
Now we declare three different SoundBuffer
objects, load three different sound files into them, and associate three different objects of the type Sound
with the related objects of the type SoundBuffer
. Add the following highlighted code:
// Control the player input
bool acceptInput = false;
// Prepare the sound
SoundBuffer chopBuffer;
chopBuffer.loadFromFile("sound/chop.wav");
Sound chop;
chop.setBuffer(chopBuffer);
SoundBuffer deathBuffer;
deathBuffer.loadFromFile("sound/death.wav");
Sound death;
death.setBuffer(deathBuffer);
// Out of time
SoundBuffer ootBuffer;
ootBuffer.loadFromFile("sound/out_of_time.wav");
Sound outOfTime;
outOfTime.setBuffer(ootBuffer);
while (window.isOpen())
{
Now we can play our first sound effect. Add the single line of code as shown next to the if
block that detects that the player has pressed the left cursor key:
// Wrap the player controls to
// Make sure we are accepting input
if (acceptInput)
{
// More code here next...
// First handle pressing the right cursor key
if (Keyboard::isKeyPressed(Keyboard::Right))
{
// Make sure the player is on the right
playerSide = side::RIGHT;
score++;
timeRemaining += (2 / score) + .15;
spriteAxe.setPosition(AXE_POSITION_RIGHT,
spriteAxe.getPosition().y);
spritePlayer.setPosition(1120, 660);
// update the branches
updateBranches(score);
// set the log flying to the left
spriteLog.setPosition(800, 600);
logSpeedX = -5000;
logActive = true;
acceptInput = false;
// Play a chop sound
chop.play();
}
Find the code that deals with the player running out of time and add the highlighted code, shown next, to play the out-of-time-related sound effect:
if (timeRemaining <= 0.f) {
// Pause the game
paused = true;
// Change the message shown to the player
messageText.setString("Out of time!!");
//Reposition the text based on its new size
FloatRect textRect = messageText.getLocalBounds();
messageText.setOrigin(textRect.left +
textRect.width / 2.0f,
textRect.top +
textRect.height / 2.0f);
messageText.setPosition(1920 / 2.0f, 1080 / 2.0f);
// Play the out of time sound
outOfTime.play();
}
Finally, to play the death sound when the player is squished, add the highlighted code to the if
block that executes when the bottom branch is on the same side as the player:
// has the player been squished by a branch?
if (branchPositions[5] == playerSide)
{
// death
paused = true;
acceptInput = false;
// Draw the gravestone
spriteRIP.setPosition(675, 660);
// hide the player
spritePlayer.setPosition(2000, 660);
messageText.setString("SQUISHED!!");
FloatRect textRect = messageText.getLocalBounds();
messageText.setOrigin(textRect.left +
textRect.width / 2.0f,
textRect.top + textRect.height / 2.0f);
messageText.setPosition(1920 / 2.0f, 1080 / 2.0f);
// Play the death sound
death.play();
}
That's it! We have finished the first game. Let's discuss some possible enhancements before we move on to the second project.
3.142.199.191