Playing Sounds.
Tonyhilliam (Talk | contribs) |
|||
(2 intermediate revisions by 2 users not shown) | |||
Line 25: | Line 25: | ||
loop to monitor this variable and will keep running until ''doorsOpen'' becomes false. | loop to monitor this variable and will keep running until ''doorsOpen'' becomes false. | ||
''World.Play2DSound()'' plays a non-positional sound, that is it can be heard anywhere | ''World.Play2DSound()'' plays a non-positional sound, that is it can be heard anywhere | ||
− | on the route. I've added a | + | on the route. I've added a call to Sleep after the sound is played, enough time to allow the |
sound to play, plus a short pause. On the next loop the method will check to see if the doors | sound to play, plus a short pause. On the next loop the method will check to see if the doors | ||
are still open and run again if so. Once they have closed the ''while'' loop and the method | are still open and run again if so. Once they have closed the ''while'' loop and the method | ||
Line 58: | Line 58: | ||
}; | }; | ||
− | I've used ''World.Play2DSound()'' to ring the bell because you will hear it no matter how far away from the shed the camera is zoomed. It would actually be more appropriate to use a different method, ''World.PlaySound()'' which will appear to come from one speaker or the other, depending on where you are, and will fall off in volume as you get further away from the building. The call for this would be <font color=blue>''World.PlaySound(me,"bell.wav",1000,10,100,me,"a.corona");''</font> You might like to try a substitution to hear the difference.<br><br> | + | I've used ''World.Play2DSound()'' to ring the bell because you will hear it no matter how far away from the shed the camera is zoomed. It would actually be more appropriate to use a different method, ''World.PlaySound()'' which will appear to come from one speaker or the other, depending on where you are, and will fall off in volume as you get further away from the building. The call for this would be <font color=blue>''World.PlaySound(me,"bell.wav",1000,10,100,me,"a.corona");''</font> (See Note 1) You might like to try a substitution to hear the difference.<br><br> |
+ | |||
+ | Note 1. If you get a compiler error for this call, try ''World.PlaySound(GetAsset(),"bell.wav",1000.0,10.0,100.0,me,"a.corona").'' There were some changes for TS12 that may prevent the original code from working. | ||
+ | |||
Next Tutorial: [[Hiding Meshes.]]<br> | Next Tutorial: [[Hiding Meshes.]]<br> | ||
+ | |||
+ | [[Getting_Started_in_TrainzScript|Back to Getting Started]] |
Latest revision as of 12:07, 17 January 2018
Trainz is capable of doing quite sophisticated tricks with sound files. We will use a file which contains a single 'ding' but loops it around continuously as long as the doors to the shed are open. This involves the use of a separate programming thread. A thread runs independently of any other code within your script. It's a bit like leaving the kettle boiling while you answer the front door, the kettle will look after itself until it boils. In the same way our thread will look after itself until something tells it to stop.
include "Buildable.gs" class Tutorial isclass Buildable { bool doorsOpen = false; public void Init(void) { inherited(); SetFXCoronaTexture("corona",null); AddHandler(me,"Object","","ObjectHandler"); } Asset GetCorona(string mesh, string effect) { Soup meshtable = GetAsset().GetConfigSoup().GetNamedSoup("mesh-table"); Soup effects = meshtable.GetNamedSoup(mesh).GetNamedSoup("effects"); KUID kuid = effects.GetNamedSoup(effect).GetNamedTagAsKUID("texture-kuid"); return World.FindAsset(kuid); } /* This is the bell ringing method, the keyword thread signifies that it is to run independently of any other code. You will remember our global variable, doorsOpen which is set to true or false in the ObjectHandler method. RingTheBell uses a while loop to monitor this variable and will keep running until doorsOpen becomes false. World.Play2DSound() plays a non-positional sound, that is it can be heard anywhere on the route. I've added a call to Sleep after the sound is played, enough time to allow the sound to play, plus a short pause. On the next loop the method will check to see if the doors are still open and run again if so. Once they have closed the while loop and the method will end. All of this runs independently of other parts of the class code. */ thread void RingTheBell(void) { while (doorsOpen) { World.Play2DSound(GetAsset(),"bell.wav"); Sleep(1.5); } } /* When the doors are opened we call the thread RingTheBell to start the bell ringing. There is no need to stop it, this will happen automatically. */ void ObjectHandler(Message msg) { Vehicle vehicle = cast<Vehicle>msg.src; if (!vehicle) return; if (msg.minor == "InnerEnter") { doorsOpen = true; SetMeshAnimationState("default", true); SetFXCoronaTexture("corona",GetCorona("default","corona")); RingTheBell(); } else if (msg.minor == "InnerLeave") { doorsOpen = false; SetMeshAnimationState("default", false); SetFXCoronaTexture("corona",null); } } };
I've used World.Play2DSound() to ring the bell because you will hear it no matter how far away from the shed the camera is zoomed. It would actually be more appropriate to use a different method, World.PlaySound() which will appear to come from one speaker or the other, depending on where you are, and will fall off in volume as you get further away from the building. The call for this would be World.PlaySound(me,"bell.wav",1000,10,100,me,"a.corona"); (See Note 1) You might like to try a substitution to hear the difference.
Note 1. If you get a compiler error for this call, try World.PlaySound(GetAsset(),"bell.wav",1000.0,10.0,100.0,me,"a.corona"). There were some changes for TS12 that may prevent the original code from working.
Next Tutorial: Hiding Meshes.