Need help with adding music in my game... (AGS 3.3.3)

Started by therealraafuru, Fri 20/03/2015 09:28:15

Previous topic - Next topic

therealraafuru

Hi, I want to add music in my game. If I simply code in "aMusicName.Play" on the script for a room it works, but when I reenter that room the music resets. I don't want it to reset... How do I go about this?

I'm a complete noob at this software, and I have almost no experience with coding...so please be patient with me!
Aw mah gawd... They killed Kenny!!!

Snarky

What's happening is that the "script for the room" (which I assume means the room_Load() or room_AfterFadeIn() function) gets called every time your character enters that room, and by calling aMusicName.Play() again, that makes the music restart (like if you double-click on a track that is playing in iTunes, it will start playing it again from the beginning).

There are two ways you could go about solving this:
1. Before you call aMusicName.Play(), check whether the song is already playing. To do that, you need to store the song that is currently playing somewhere. The easiest is to create a Global Variable of type "AudioChannel*". You can call it "currentMusic", for example. Now instead of aMusicName.Play(), write it like this:

Code: AGS
if(currentMusic == null || currentMusic.PlayingClip != aMusicName)
  currentMusic = aMusicName.Play(); // You can also give it arguments so it will loop


Now it will only call aMusicName.Play() if it's not playing any music (currentMusic == null), or if it's playing something different than aMusicName (currentMusic.PlayingClip != aMusicName). And it will update currentMusic to let it know that we're playing aMusicName.

(This relies on the game being set to have only one audio channel for music, and aMusicName being of type music.)

2. The other point is that if the music isn't tied specifically to this room, you might want to use the global script instead of the room script to start playing it (that way it won't trigger the play command each time you enter), but this depends on the exact logic of you game.

therealraafuru

OK, cool.
This particular track plays in multiple rooms. If I use the global script, then what is the code I need to put in?
Aw mah gawd... They killed Kenny!!!

Slasher

If the music is the same when you leave the room it does not change or restart but continues, and when you return, this works for me:

In Global asc:
Code: ags

function on_event (EventType event, int data) {
 AudioChannel *bgm;
 void SetBGM(AudioClip *music) {
 if (bgm != null && bgm.PlayingClip == music) return; // don't if music is already playing
 bgm = music.Play();
} 
}


The music continues to play when you change rooms without restarting from the start until you change it.



Haggis

There used to be a Music Continuity module for this which was very useful but I believe it became redundant when the sound/music overhaul was made for version 3.2

http://www.adventuregamestudio.co.uk/forums/index.php?topic=26262.msg331933#msg331933


I managed to fix it up in my current game back into a working state - but given my basic programming skills I rebuilt it in GlobalScript rather than in a separate module script. It works using structs and arrays I believe to store tracks, the room they play in, and the timestamp of where the track was when the player was last in the room (and to therefore continue playing from when the room is loaded again).

I have to say Slasher's code is much more concise though.

therealraafuru

OK, I have tried Snarky's method and it works. Thanks a ton, Snarky. :-D
Aw mah gawd... They killed Kenny!!!

Grim

That's a very useful thing I learned from Snarky here, so big thanks!:) - I never actually knew how to check if the current track is playing...

The simplest way to do it in my opinion is to use Game.DoOnceOnly command. That way you only trigger music to play once and next times you enter the room the command will be ignored.

monkey0506

Quote from: slasher on Fri 20/03/2015 13:13:17...this works for me:

In Global asc:
Code: ags
function on_event (EventType event, int data) {
 AudioChannel *bgm;
 void SetBGM(AudioClip *music) {
 if (bgm != null && bgm.PlayingClip == music) return; // don't if music is already playing
 bgm = music.Play();
} 
}

No it doesn't. AGS does not support nested functions, which is exactly what you've posted here. You're also (making an attempt at) "calling" this nested function every single time any event (that is handled by on_event, of course) occurs. Your nested function also would never do anything as you are creating a pointer (which defaults to null) immediately before checking that it is not null. Here's an amended version of what you were trying to suggest (for posterity's sake):

Code: ags
AudioChannel *bgm;

void SetBGM(AudioClip *music)
{
  if (bgm != null && bgm.PlayingClip == music) return; // don't play the music if it's already playing
  bgm = music.Play();
}

function on_event (EventType event, int data)
{
  if (event == eEventEnterRoomBeforeFadein)
  {
    SetBGM(aMusicName);
  }
}

SMF spam blocked by CleanTalk