Music playlists?

Started by FamousAdventurer77, Sat 02/07/2011 00:32:34

Previous topic - Next topic

FamousAdventurer77

This isn't exactly a scripting question per se, more a theory question which will eventually be put into action.

Since I've done a little more reading up and gotten a little more practical experience with my test game, I think I'm ready to make my first short game.
My design is that it's about 13 rooms (I say "about" since some I'm not sure if it will necessitate a separate room or usage of a graphic array instead) and the music goes something like this:

Room 1: Start-up screen-- just one song that plays on repeat, you never hear it anywhere else
Room 2: Only used in the intro cutscene, one song plays just once then never heard again, room never revisited
Room 3: Only seen once in the intro cutscene, no music just ambient sound

Rooms 4-13: Want a 5-song playlist where it doesn't matter what room you're in, what's going on, etc. It's what the player will be hearing most of the entire game. 5 songs that, if I were using an ipod, would be on Shuffle and Repeat.

Until the ending sequence, when the music will stop, there will be one more short song, then the credits get their own song.


I have a basic understanding of how to do it all except the playlist bit.
Help would be appreciated but don't give me code outrightly-- lemme get my brain picked for a bit until I beg for mercy :) How the hell else will I learn the language eh?
If you want to know the Bible's contents, just watch Lord of the Rings or listen to the last 8 Blind Guardian albums. It's pretty much the same thing.

Wyz

Right, interesting concept. :D

I don't have much experience with the new audio system but I think I'd use repeatedly execute to check if something is playing. When nothing is playing I'd use the random number generator to decide what to play next. If it is the same song as the one that just played (store that in a variable) I'd choose the next one. It might not be the most optimal solution so maybe someone else has a better idea. :)
Life is like an adventure without the pixel hunts.

FamousAdventurer77

I knew that the random number generator would come into play here, but I'm not sure how to execute it under repeatedly_execute once the player starts the game, and sits through or skips the intro, then the playlist stops once the end is nigh.

Maybe I'm being a bit ambitious for my first game, but I figure I don't mind picking my brain for music scripting since I plan on music being a huge part of my games since an animator I am not.  :=
If you want to know the Bible's contents, just watch Lord of the Rings or listen to the last 8 Blind Guardian albums. It's pretty much the same thing.

monkey0506

It's not actually very difficult at all. What I would do is just use an AudioChannel*, start and stop it as needed, set the pointer to null when stopping the channel, and then use the IsPlaying property of the non-null pointer to control when the next track should play. If that's not clear, hopefully this code will help clarify things.

First off, in the Global Variables pane create an AudioChannel* called acPlaylist (alternately you can just define it in the script and use import and export to make it global, whichever is easiest for you).

Next we'll create some functions to handle the "bulk" work of selecting the next playlist track. We haven't started anything playing yet, so acPlaylist is still null right now, but this is just some more setup to simplify things later and save us having to duplicate code. For this example we'll put the functions in GlobalScript.asc, but if you need to use it in a higher script remember you'll have to move the functions to the top-most script that needs to use it!

Code: ags
int GetPlaylistID(this AudioClip*)
{ // we'll use this internally to check a track's index in the playlist
  if (this == aPlaylist1) return 0; // name the tracks whatever you want, but we'll use 0-based indexing
  else if (this == aPlaylist2) return 1;
  else if (this == aPlaylist3) return 2;
  else if (this == aPlaylist4) return 3;
  else if (this == aPlaylist5) return 4;
  else return -1;
}

AudioClip* GetPlaylistClipByID(int id)
{ // this is the counterpart to the above, and is also for internal use
  if (id == 0) return aPlaylist1;
  else if (id == 1) return aPlaylist2;
  else if (id == 2) return aPlaylist3;
  else if (id == 3) return aPlaylist4;
  else if (id == 4) return aPlaylist5;
  else return null;
}

void PlaylistPlayNext()
{
  if ((acPlaylist == null) || (acPlaylist.IsPlaying)) return; // our channel is null, or is still playing the current clip: do nothing
  int ran = Random(4); // 0-4 gives us 5 values, increase as needed
  int playingClipID = acPlaylist.PlayingClip.GetPlaylistID();
  while (ran == playingClipID) ran = Random(4); // make sure we haven't selected the currently playing clip over again
  AudioClip *next = GetPlaylistClipByID(ran);
  acPlaylist = next.Play();
}


Then, make sure your room 4 (or whichever is the first to have the playlist playing) has a room_Load function set. In the room script, do this:

Code: ags
// room4.asc

function room_Load()
{
  if (acPlaylist == null)
  {
    AudioClip *clip = GetPlaylistClipByID(Random(4)); // grab a random clip
    acPlaylist = clip.Play(); // start the playlist
    // do this later if you need to restart the playlist
  }
}


After that, in your GlobalScript.asc do this:

Code: ags
function repeatedly_execute()
{
  PlaylistPlayNext();
}


So with that your playlist will now start when you enter room 4, and continuously shuffle to a new song once that one is finished.

To stop the playlist, just do this:

Code: ags
  if (acPlaylist != null)
    acPlaylist.Stop();
    acPlaylist = null; // prevent it from just playing the next track
  }


This example is a bit naiive in that it doesn't check that it's played all of the clips before it might replay one of them, it only shuffles repeatedly. That would actually be pretty easy to take care of as well, but I'm on my phone and this whorish stock web browser is about to make me pull my teeth out and thrust them through my eyes just so I can drown it in the blood gushing out of my eye sockets.

So, I'll take a look at that when I get home. ;)

FamousAdventurer77

Damn thanks!! But I did want to be clued in vs. receiving code right away ;) I still need to improve my grasp of the language before I can implement this. But I definitely appreciate the help.

Pretty much, the playlist will be continuous on repeat until the endgame sequence-- basically how like in LSL5, there's that 3-song playlist during the K-RAP portion of the game-- it's only a couple rooms, and you never hear different music on those screens then it's never heard again after that part of the game. Except that mine has 5 songs. Same concept.

Basically, the playlist will start once. Then stop once. That's it. But if I utilize this concept in the future, I'll definitely be revisiting this code to make it more flexible for games where the player will re-visit an area (opposed to just one room) and the playlist will start/stop more than once.


Quote from: monkE3y_05_06 on Sat 02/07/2011 06:47:44
this whorish stock web browser is about to make me pull my teeth out and thrust them through my eyes just so I can drown it in the blood gushing out of my eye sockets.

That sums up how I feel about OpenOffice!
If you want to know the Bible's contents, just watch Lord of the Rings or listen to the last 8 Blind Guardian albums. It's pretty much the same thing.

monkey0506

Hey FamousAdventurer, you inspired me! Check out the Playlist module to fulfill all your playlist needs! :=

SMF spam blocked by CleanTalk