Hello everybody,I wrote a function that switch music when called and it just works fine when I define it in room script. But, as I have to use it, together with another one, inside a dialog, I put them both in global.
In global.ash
Spoiler
enum actions
{
eGoUp,
eGoDown
};
import void SetBackgroundMusic(actions action);
import void stopMusic();
AudioChannel* channel[5];
AudioClip * clip[5];
int position[5]; //position of the clip once it's paused
int choice = 1; //clip ID for channel 1 only
int number = 0; //clip and audio channel ID
In global.asc
Spoiler
void SetBackgroundMusic(actions action)
{
switch(choice)
{
case 1: clip[1] = aSong11;
break;
case 2: clip[1] = aSong12;
break;
case 3: clip[1] = aSong13;
break;
case 4: clip[1] = aSong14;
break;
}
clip[2] = aSong2;
clip[3] = aSong3;
clip[4] = aSong4;
if(channel[number].IsPlaying) //volume down
{
while(channel[number].Volume > 0)
{
channel[number].Volume -= 3;
Wait(2);
}
channel[number].Pause();
position[number] = channel[number].Position;
}
if(action == eGoDown && number > 0) number--;
else if(action == eGoUp && number < 4) number++;
if(channel[number] == null || !channel[number].IsPaused channel[number] = clip[number].Play(); //assign new audio clip to channel
else clip[number].PlayFrom(position[number]); //else play it from where it was paused
channel[number].Volume = 0;
if(channel[number].IsPlaying) //volume up
{
while(channel[number].Volume < 99)
{
channel[number].Volume += 3;
Wait(2);
}
}
}
void stopMusic() //used for channel 1 only, for which, inside a dialog, player can choose which song to play
{
if(channel[number] == null) Display("null");
while(channel[1].Volume > 0)
{
channel[1].Volume -= 3;
Wait(2);
}
channel[1].Stop();
}
In room.asc
Spoiler
function room_AfterFadeIn()
{
channel = aSong0.Play();
channel.Volume = 99;
}
I didn't always check the null condition, I used Display function just to see when the audio channel stop being non null, in one case it was inside a dialog, but I don't really understand how to work on this. Please consider that this is just a raw try, as I'm moving my first steps into music functions. SetBackgroundMusic worked only when it was defined inside room. I still don't understand how to point to channels and clips globally, if and where to use imports, exports etc... Any help is appreciated.
Thank you,
Giacomo
Looks like you are creating variables and arrays in a header.
This means that every script gets a separate copy of these variables/arrays, so even after you set them in one script they remain null when you try to access them from another.
What you have to do is create them in the script, export them there, and only import them in the header.
Exactly, for example you have this
// header
AudioChannel* channel[5];
Change that to
// header
import AudioChannel* channel[5];
// script
AudioChannel* channel[5]; export channel; // exporting requires just the name
Same for all other variables.
On that note, the global script header says:
// Main header script - this will be included into every script in
// the game (local and global). Do not place functions here; rather,
// place import definitions and #define names here to be used by all
// scripts.
Maybe we could change that message to explicitly state not to declare variables here either?
I think ideally the compiler should raise an error—or even better, a warning in the IDE before you even try to build. This is such a common mistake.
Perhaps something like that is possible to implement with the new compiler in AGS 4? (Note: I'm using "compiler" loosely; it might be some other step in the build chain.)
Thank you very much! It works perfectly. Now it's clearer how to export, import variables and I'll practice this more on separeted scripts, where I couldn't understand how to use import/export for functions...Thanks again.