3D Sound
I mentioned in my Sound Manager tutorial that I was still playing with 3D sound and I didn’t include it in the tutorial itself. Well, I have been playing with it and finally got it working. I’m going to be recording an update soon which will cover fixes/changes to the Image, SpriteSheet and Sound Manager classes, plus some overall structural changes to the project.
The one thing that did take me a while to figure out was that I needed to be using Mono sounds for the 3D side of OpenAL to work. I was setting the location of the listener and the location of the source but the sound was not changing based on its position with the listener.
I kept reading up on what could be wrong and came across an obscure post which said that you needed to use Mono sounds for OpenAL to correctly play the sound in 3D. This is because stereo sound is already playing out of both the left and right channels so OpenAL is not sure what to do with the sound. When it is Mono OpenAL can apply that mono sound to which ever channel it needs to to give the 3D effect.
So, with that sorted the Sound Manager will now support 3D sound :o)
I think there is still some tweaking to do so that the sound does not get too quiet too quickly when it moves away from the listener, but in general its working OK.
I’ll try to get the update done ASAP to give you the necessary updates.
Mike
10 Comments
A Person on June 9th, 2009
Hey mike i gotten a lot of my collision detection class done and most of its working great except for layer collision detection so i can make layers a solid object if i want, i have object to object collision working great so here is my layer code which can get the collision for the second tile it hits (for some reason it skips the first) and it starts to move all jittery, the jiterryness can be fixed by giving a very very low speed but i still am not satisfied. So now the code.
- (void)detectCollisionForLayerNumber:(int)number rectObject:(Image*)objectOne speed:(CGPoint)speed delta:(float)delta direction:(int)direction {
tileY = 0;
tileX = 0;
Layer *layer = [tiledMap.layers objectAtIndex:number];
while(tileY < layer.layerHeight) {
while(tileX < layer.layerWidth) {
int globalID = [layer getGlobalTileIDAtX:tileX y:tileY];
if(globalID != 0) {
if([self rectObject:objectOne collisionWithRect:CGRectMake((tileX + 1) * [tiledMap tileWidth] - [tiledMap tileWidth], (tileY + 1) * [tiledMap tileHeight] - [tiledMap tileHeight], tiledMap.tileWidth, tiledMap.tileHeight)]) {
if(direction == kDirection_Forward) {
objectOne.origin = CGPointMake(objectOne.origin.x - speed.x * delta, objectOne.origin.y - speed.y * delta);
} else if(direction == kDirection_Backwards) {
objectOne.origin = CGPointMake(objectOne.origin.x + speed.x * delta, objectOne.origin.y + speed.y * delta);
}
}
}
tileX++;
}
tileY++;
tileX = 0;
}
}
This isn’t how i normally do this but i dont really care about doing anything else but stoping the object from going through that layer. Normally i return a yes or no and then i do what i what (that works). I’ve also tried getting info from the xml file without much success. I also made changes to the image class and tiledmap class to support what i’m doing for example origin and the layers array. These changes work and i’ve tried them multiple ways and it works but it keeps coming back to this method. No errors are given to me on build so if there is a ; missing or something its not that it was my copy and paste error.
Hope you can help mike and thanks for the great work you already been doing
A Person on June 9th, 2009
sorry mike i don’t know what happened but i used the code but it didn’t work
A Person on June 9th, 2009
i meant the code tag (i typed and it dissapeared)
A Person on June 9th, 2009
I think I see my mistake I have to use the actually map point in there some where not to hard to figure out.
mike on June 9th, 2009
@A Person, thanks for the comment. I’ve not had a chance to look through your code in detail yet, but I’ll check it out later.
What I tend to do with the tile map is set a property on tile images which should block the player, something like blocked = true.
When I load up the tile map I then run through the properties for each tile in the map and creation a collision map which is just an array that stores either a 0 or 1 for each tile in the map. If the map tile blocks then the array is 1 else it is 0.
When I am then moving the player, I convert the players pixel coordinates into a tile map, simply by dividing the pixel location by the tilewidth/height etc. If that shows that moving the player would place them in a blocked tile I reverse the movement and leave them where they were.
Doing this is very simple and has worked well in the past. I’ll take a look at your code a little later.
Mike
A Person on June 10th, 2009
Thanks mike that’s actually what I did on my first go at this so I’ll revisit it and see what wasn’t working.
A Person on June 13th, 2009
Hey mike its me again and same for the same thing.
I still can’t get the tiledMap layer collision detection to work and i’ve tried many ways but it seems to be that the tile map is rendered by a mapX and mapY and a width and height along with a mapoint which makes finding out where the tiles are and if they are solid hard and i was wondering how your progress is with this.
Hope you can help and thanks for all your work so far
mike on June 13th, 2009
Hi A Person
This is something I am putting into Tutorial 10 now. It can be hard to work this stuff through so I’m adding it to the next tutorial which will be out ASAP.
Hopefully that will be in time to help you.
Mike
MarsMan on July 8th, 2009
Mike- So many of us would dearly love to see an openAL tutorial on the creation of a musical instrument (like an electric guitar (using audio samples) with pitch bend capability.
Your tutorials ROCK my friend!




mike on June 4th, 2009
I’ve managed to work out why the volume was dropping off so quickly as well now. There are a number of settings which can define the type of operation you want to use for distance attenuation. I’ve not investigated them all yet, but you can add the following line of code to set a reference distance for a sound source and control how quickly the volume drops off as the sound source moves away from the listener.
If you play with the value you will see how it effects the volume drop off.
From the documentation it would seem that for most needs in a 2D game the linear distance rolloff model would seem to be valid. This is where the volume drops off in a linear manner based on the distance from the source to the listener.
The command to set the model you want to use is
Possible model names are:
There are also other options that can be set such as
which can be used to help tune the OpenAL model to your needs.
I’m making changes to the SoundManager at the moment and I’ll post the changes. The documentation at the following location has of course been useful ;o)
http://connect.creativelabs.co.....cation.pdf
Mike