-
Notifications
You must be signed in to change notification settings - Fork 20
Basic Sound
In a typical game, there is a music, playing in the background and sound effects, produced on certain events in the game. In this part, I'm going to add some basic sound effects.
Sound effects are either synthesized from scratch, or prerecorded samples are used.
A couple of cites to look for samples are OpenGameArt and Freesound. Another possibility is to look for instrument samples pack, which are often bundled with music-making software (such as LMMS or Hydrogen).
In dealing with samples, Audacity is immensely helpful tool. It allows to extract a part of the track, normalize volume, suppress certain frequencies, and so on. The number of available editing options is more than enough.
Of course, instead of using someone else's samples, you can record your own. It is possible to get a decent result (enough to convey the idea) with minimal effort, such possibility should not be completely discarded. Audacity makes recording process simple enough. For example, one of the sounds for this game is a tea cup hit by a pen, recorded on the internal microphone of my computer.
If you are looking for chiptune effects, bfxr/sfxr programs can be helpful (a Lua port of sfxr exists ).
When dealing with samples, my advice is to keep track of all file renames. They would be necessary to compile proper credits list.
In LÖVE the sounds are stored and played by audio sources, which are
a part of the love.audio
module. Each source stores a single sound, which is commonly specified on source creation. When needed, the sound can be played with the play
method of the source.
In our game, sound effects are produced only on collisions. I'll desribe only ball collision with brick of simple type. The rest is similar.
Typically first you load sound. This is a class variable. ( code )
Then in collision response you play it: ( code snd:play() )
However, I want several different sound and select randomly one of them to play. Insted of doing it manually, I use TAsound library [link]. It takes automatically manages random sounds.
Besides, it simplifies music playing. We to take care and ensure that there is only instance of TEsound across all gamestates.
First, we need to load sounds from the HDD. It is good to make them class variables, just like tileset image. I have more than one sound for ball-brick collision and I want to randomly play one of them. I create a table to store the sounds.
simple_break_sound = {
love.audio.newSource("sounds/simple_break/recordered_glass_norm.ogg",
"static"),
love.audio.newSource("sounds/simple_break/edgardedition_glass_hit_norm.ogg",
"static") }
A good place to play the sound is react_on_ball_collision method. We select a random sound from the table and play it.
......
if self:is_simple() then
self.to_destroy = true
local snd = simple_break_sound[ math.random( #simple_break_sound ) ]
snd:play()
elseif self:is_armored() then
......
Same for collision of the ball with other brick types and platform-ball, ball-wall, and platform-bonus collisions.
Since we are using math.random, don't forget to seed it. This is done in love.load with math.randomseed function.
function love.load() math.randomseed( os.time() ) local love_window_width = 800
....
end
Now to the music.
On OGA you can also find some music. Another great resource is Jamendo[link], where you can find a lot of CreativeCommons-licensed music.
The game is short, so I use only one song. I set it to loop. It starts playing in the menu and goes on until you quit the game.
music = love.audio.newSource( "sounds/music/S31-Night Prowler.ogg" ) music:setLooping( true )
function menu:enter() ..... music:play() end
The game is simple, so I've used love.sound callbacks directly instead of any external sound management libraries. But in more complex cases it might be a good idea to use TEsound [link] library, which could simplify sound management.
Feedback is crucial to improve the tutorial!
Let me know if you have any questions, critique, suggestions or just any other ideas.
Chapter 1: Prototype
- The Ball, The Brick, The Platform
- Game Objects as Lua Tables
- Bricks and Walls
- Detecting Collisions
- Resolving Collisions
- Levels
Appendix A: Storing Levels as Strings
Appendix B: Optimized Collision Detection (draft)
Chapter 2: General Code Structure
- Splitting Code into Several Files
- Loading Levels from Files
- Straightforward Gamestates
- Advanced Gamestates
- Basic Tiles
- Different Brick Types
- Basic Sound
- Game Over
Appendix C: Stricter Modules (draft)
Appendix D-1: Intro to Classes (draft)
Appendix D-2: Chapter 2 Using Classes.
Chapter 3 (deprecated): Details
- Improved Ball Rebounds
- Ball Launch From Platform (Two Objects Moving Together)
- Mouse Controls
- Spawning Bonuses
- Bonus Effects
- Glue Bonus
- Add New Ball Bonus
- Life and Next Level Bonuses
- Random Bonuses
- Menu Buttons
- Wall Tiles
- Side Panel
- Score
- Fonts
- More Sounds
- Final Screen
- Packaging
Appendix D: GUI Layouts
Appendix E: Love-release and Love.js
Beyond Programming: