Victorious is correct.
The sound pool helps with fire-and-forget sounds, it helps position sounds and move the listener with minimal effort, and it cleans up after itself.
There are two ways to access individual sounds in the sound pool: use the slot variable returned by the play methods, and pass it to other methods for updating sounds, or hunt down the sound objects that the pool uses directly. You almost never need to do the latter--the only case I can think of off the top of my head is if you need to do something like fade or pitch bend all of the sounds in the pool at once, since there aren't already methods for that.
As for the pool cleaning up sounds that have finished playing, the play methods do have an optional "persistent" parameter, with which you can prevent sounds from being automatically destroyed. You generally wouldn't need this, unless it's to let another object keep track of a sound that can change--for example, if you wanted an enemy to be able to say a variety of things, but only one at a time.
So, you might have an enemy or vehicle class with a slot property, to keep track of its sound.
sound_pool pool; // Global pool.
int player_x=0, player_y=0; // These are global for this example. In practice, a class for the player is usually a good idea, so I usually have a global vector for the camera instead.
class moving_object {
int x=0, y=0;
int slot=-1; // This will be used to move sounds in the sound pool.
string[] sounds; // play one of these at random
moving_object() {}
moving_object(int xx, int yy) {
this.x=xx;
this.y=yy;
}
void move(int dx, int dy) {
this.x+=dx;
this.y+=dy;
if(this.slot<0 or pool.sound_is_playing(this.slot)==false)
{
if(this.slot>=0) pool.destroy_sound(this.slot);
this.slot=pool.play_2d(this.sounds[random(0, this.sounds.length()-1)], player_x, player_y, this.x, this.y, false, true);
}
pool.update_sound_2d(this.slot, this.x, this.y);
}
}
timer time;
void main() {
// Set up sound pool properties, maybe play some looping ambience.
// Set up the moving objects:
moving_object@[] objects(4);
string[] sounds={"sounds/growl1.wav", "sounds/growl2.wav", "sounds/growl3.wav", "sounds/growl4.wav"};
for(uint i=0; i<objects.length(); i++) {
moving_object mo(random(-30, 30), random(-30, 30));
mo.sounds=sounds;
@(objects[i])=mo;
}
// Create the window and start the main loop:
show_game_window("Sound pool example");
while(true) {
if(key_pressed(KEY_ESCAPE)) exit();
else if(key_pressed(KEY_LEFT)) player_move(-1, 0);
else if(key_pressed(KEY_RIGHT)) player_move(1, 0);
else if(key_pressed(KEY_UP)) player_move(0, 1);
else if(key_pressed(KEY_DOWN)) player_move(0, -1);
// Update the moving objects:
if(time.elapsed>500) {
for(uint i=0; i<objects.length(); i++) {
int dx=0;
if(objects[i].x<player_x) dx=1;
else if(objects[i].x>player_x) dx=-1;
if(objects[i].y<player_y) dy=1;
else if(objects[i].y>player_y) dy=-1;
objects[i].move(dx, dy);
}
time.restart();
time.resume(); // I can never remember if this is necessary after restart.
}
wait(5);
}
}
// Move the player, updating the listener position in the process.
void player_move(int dx, int dy) {
if(player_x+dx<-30 or player_x+dx>30) pool.play_stationary("sounds/bump.wav", false);
else player_x+=dx;
if(player_y+dy<-30 or player_y+dy>30) play_stationary("sounds/bump.wav", false);
else player_y+=dy;
pool.play_stationary("sounds/step" + random(1, 3) + ".wav", false);
pool.update_listener_2d(player_x, player_y);
}
If this only made things more confusing, let me know so I can try to fix it.
看過來!
"If you want utopia but reality gives you Lovecraft, you don't give up, you carve your utopia out of the corpses of dead gods."
MaxAngor wrote:
George... Don't do that.