Implementing footstep sound effects

Last week I designed some footstep sound effects. One of the tasks I had this week was to implement them into the playable alpha version of our game. I started by cutting up the footstep sound file into 6 short files, each with a separate footstep. I wanted a system that plays sounds with a set interval that depends on the speed of the enemy, and I also wanted it to randomly select one of the 6 different files for each footstep. I solved this by adding variables to the enemy class that holds the position where the enemy was when it lasted played a footstep sound. Each tick, there is a test whether the distance between this position and the enemy’s current position is greater than a constant value which is the footstep length. If true, one of the 6 sounds is picked randomly and played, and the “previous position” coordinates are updated. The code in the update function looks like this:


    if (sqrtf(pow(m_x - m_prevPos.x, 2) + pow(m_y - m_prevPos.y, 2)) > footStepLength)
        {
            int random = static_cast<int>(round(rand() % m_stepSounds.size() + 1) - 1);
            playStepSound(FLOOR_WOOD_BASEMENT, random);
            m_prevPos.x = m_x;
            m_prevPos.y = m_y;
        }

 

The “playStepSound()” function takes two parameters, the first one is the type of floor, because this will ultimately affect how the footsteps sound although I haven’t implemented it yet. The second parameter is a randomly generated integer deciding which index of footsteps is to be played.

The next step was to make the sounds change depending on the positions of the enemy and the avatar. This was achieved with the built-in SFML effects for “spatialization”. There is one “Listener” object. This is basically like a pair of virtual ears for which the position can be set at any time. Every sound source is also given a position, and then every sound coming out of the speakers is automatically adjusted based on the relation between the positions of the sound source and the Listener respectively, as well as a few other factors. The “other factors” I actually used where the “attenuation” and “minimum distance” which basically decide how much, and by what factor, the sound is affected by distance. An example of a function I didn’t use is the Listener’s direction, because we do not want to hear the sounds from the avatar’s actual perspective as we would in a first-person perspective game.

So what I do in the code is updating the Listener’s position to the avatar’s. The attenuation and minimum distance of the sound sources only have to be set once for each sound. This is done directly after each sound is loaded into memory. What has to be updated for each sound source is its position. It would be unnecessary to update all the sounds’ positions each tick, so instead I made the position update for only the sound that’s about to be played, in the function where it’s played, like so:


void Enemy::playStepSound(EFloorType floorType, int index)
{
    switch (floorType)
    {
    case FLOOR_WOOD_NICE:
        m_stepSounds[index].setPosition(m_x, 0.0f, m_y);
            m_stepSounds[index].play();
            break;
    }
}


 

Note that the position is in 3D coordinates. This is just how the spatialization functions work. Since our game is in 2D I leave the y coordinate at zero. (The 3D coordinate system is defined so the 2D “y” becomes the 3D “z”.)

The biggest problem I had with the spatialization was that I realized only after like 2 hours that it doesn’t work at all with stereo sounds. The fix was as simple as to convert my sound files to mono.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s