Sony Playstation Portable Lua Programming: Sound and Music
Now, it's time to add some sound to our projects. Every game needs sound, and here we will tackle just how to do it in luaplayer.
Let's get started!
Applying Sound
luaplayer can play the the following formats: UNI, IT, XM, S3M, MOD, MTM, STM, DSM, MED, FAR, ULT or 669 for music. WAV files can be used for sound.It is possible to convert MIDI files into the above mentioned formats.One program that can do this is Modplug Tracker. Also, keep in mind that luaplayer DOES NOT support mp3 files.
After we learn a few sound commands we will apply these with some things we learned previously to create a small program.
Let's take a look at our first command. This command will play a music file.
Music.playFile( string file, bool loop )
Now, where "string file" is you will use the name of your music file, such as "song.xm".
"bool loop" is where you will either put true or false. true will loop the song over and over, and false will only play through the song once. Here's an example of playing a song.
Music.playFile("mysong.mod", true)
Now, have a look at these commands. The following can be used after you have starting playing your music file.
Music.pause()
Music.stop()
Music.resume()
These are pretty much self explanatory.
Music.pause() will pause your song.
Music.stop() will stop your song.
Music.resume() will resume your song if you have temporarily stopped it.
There is also a command we can use to test whether a song is playing or not. This will return either true or false. Take a look:
Music.playing()
Say we wanted to test if our song is playing, and if it is then print a message to the screen. We could do..
if Music.playing() == true then
screen:print(10,10,"Music is playing",white)
end
There's also a command to set the volume of the music file. In the parentheses simply place a number from 0 to 128. Here's the command.
Music.volume(Number)
Now, let's learn a bit about sound files for sound effects, particularly wav files. These are done slightly different than playing music files. Here's how to load a sound.
bonkSound = Sound.load("bonk.wav",false)
The wav file is loaded into a variable and later we use the variable to refer to the sound. We used false here so that it will not loop over and over. Remember using true will make it loop, if that's what you need.
Something very important about WAV files in luaplayer is that they must be mono and not stereo. You can check this by right clicking on the file and go to properties and then summary to see.
Let's learn a few more commands now. The next command will play the file. Use the name of the variable you used to load your sound. Like this:
bonkSound:play()
I do not recommend using this way to play the file however. This can lead to a common error which will mention something along the lines of "loop ingettable". Here's how I would play my file. The only thing you would need to change from this code is the bonkSound if you used a different variable.
local sound = bonkSound
voice = sound:play()
To stop the sound use:
voice:stop()
We can also use a command as we did with the music commands to see if the sound is playing. This command is:
voice:playing()
There are other sound and music commands for you to discover out there, but these are good enough to get you using sounds and music.
Let's Make Something:
Now, we are going to create a little program. This will start us off in a menu screen where we will be able to select a blue or black background. When X is pressed the program will move on to the next part with the background colored as we chose. In this part of the program it will display how many times the program has been executed. How? Well, each time we press X in the menu screen it will open up a file that we will create shortly, and write a number to the file. The program also reads the number from the file and stores it into a variable. If you completely exit the program and return to it later, it still will show how many times it has been ran, since it is stored in a file. So let's get busy.
First, I want you to create a normal txt file with notepad or whatever you may use. Inside the text file type in the number 0. Inside your file should look like this:
0
Save this file as counter.txt, just a normal text file.
Let's start our lua file now. First we will create a few color objects for us to use.
white = Color.new(255,255,255)
blue = Color.new(0,0,255)
black = Color.new(0,0,0)
Next, a few variables.
oldpad = Controls.read()
startcolor = black
gamestate = "menu"
oldpad will store the last button we pressed.
startcolor stores the color that we will use to start the second half of the program later on. We start with black.
gamestate is what we will use to see which function to use. We will make two functions. One will run the menu, and the other will run the rest of our program. Since we start at the menu that's our starting value for the variable.
Our next part deals with some sound!. First, I want you to download these two very small WAV files, into your program directory.
Beep and
Goodbye
Now, lets load up these wav files into our program. We don't want them to loop so we will use false.
menusound = Sound.load("beep.wav",false)
goodbye = Sound.load("goodbye.wav",false)
Simple enough! Remember those file commands from the last tutorial?! Well here's a reminder.
At this point we will open up our counter.txt file we created and read the value from it into the variable counter.
file = io.open("counter.txt", "r")
counter = file:read("*n")
file:close()
Notice we used "*n" to read in a number.
Now, we will create a table for our start screen selector. These will contain an image that we create to use as the selector, as well as it's x and y values. The command below the table clears our selector image to the color blue. Here's the code:
selector = { image = Image.createEmpty(145,15), x = 147,y = 77 }
selector.image:clear(blue)
Now, we will create a function called drawMenu() that will perform all the necessary tasks for the menu. Here's the opener:
function drawMenu()
We will use this function as a looping function so each loop let's clear the screen and get readings from the controls. Next code:
screen:clear()
pad = Controls.read()
Next, we are going to blit our selector to the screen and print two lines of text. Here's the code:
screen:blit(selector.x,selector.y,selector.image)
screen:print(150,80,"Start Game (Black)",white)
screen:print(150,100,"Start Game (Blue)",white)
Notice how we used our tables values to blit the selector to the screen. This selector image will move up and down to highlight the menu choice that is selected. We want to be sure to blit this before printing the text, or else it will blit over the text.
Our two lines of text printed will be our options to the player. Either start the game with a black screen, or a blue one.
Our next few sections inside the function will check for button presses. Let's do up first.
if pad:up() and oldpad:up() ~= pad:up() then
selector.y = 77
startcolor = black
local sound = menusound
voice = sound:play()
end
First this code says that if up is pressed and if up wasnt the last button pressed then.....
The next line sets the y value of selector to 77. This is to paste the image around the text to make it appear to be selected.
Now, we set the startcolor to black.
Next we play the menusound wav file using the method I recommended earlier.
Now, we will do down. This is done exactly the same except that we set the image a bit lower, and we set the color to blue. Here's the code
if pad:down() and oldpad:down() ~= pad:down() then
selector.y = 97
startcolor = blue
local sound = menusound
voice = sound:play()
end
Now, we will do the X button.
if pad:cross() and oldpad:cross() ~= pad:cross() then
gamestate = "game"
counter = counter + 1
file = io.open("counter.txt","w")
file:write(counter)
file:close()
end
end
In this we set our gamestate to "game" so that the menu code will no longer get performed (once we code the rest).
We increase our counter variable by 1.
After this we open our txt file and write the new value of counter into the file, replacing the old value in the file.
Don't forget to close the file.
Note, the extra end is to close the function. This function is done!
Our next function will perform the rest of the game after we leave the menu. This function is rather small and simple, so here's the entire function.
function playGame()
screen:clear(startcolor)
pad = Controls.read()
screen:print(100,100,"This program has been executed " .. counter .. " times.",white)
screen:print(100,110,"Press Start to exit to Menu",white)
if pad:start() then
gamestate = "menu"
local sound = goodbye
voice = sound:play()
end
end
In this function notice we clear the screen with the color you select from the menu using the startcolor variable.
Two messages are printed, and a check for the start button. This will set the gamestate back to menu if start is pressed, and play a wav file.
Next we start our main program loop. This is very short and easy thanks to our functions. In the loop we will check which state the game is in and perform the function for that state. Here it is!
while true do
if gamestate == "menu" then
drawMenu()
end
if gamestate == "game" then
playGame()
end
screen.flip()
oldpad = pad
end
...and next... Oh yeah! That's it! Run it and give it a try.
Reading/Writing Files |
Timers
|