Play Sound on object bounce

I’m using collision detection to play sound when object bounces

local function ballBounce(  self, event )     if ( event.phase == "ended" ) then         audio.play(bounce)     end end

which works well but when ball stops bouncing and is just rolling on the ground the sounds play several times per second. Any suggestion how to modify the function to ignore rolling?

Hi @radim.simanek,

You may want to play the sound on the “began” phase instead of “ended”. However, this might not prevent the repeating sound, because the ball may be “breaking collision” at a very slight level (almost not visible to you, but visible to the physics engine).

One solution would be to surround the ball with another body element that is just slightly larger and set as a sensor (so it doesn’t cause any physical response). Then, on collision, you detect if that specific element collides, and you play the sound… but you don’t play the sound if the main body of the ball collides.

Hope this helps,

Brent

thanks for very fast response. I figured out this and it works reasonably well

local function ballBounce(  self, event ) local velocity = self:getLinearVelocity() if math.abs(velocity) \> 30 and ( event.phase == "ended" ) then audio.play(bounce) end end

Yes, that’s valid too. Note, however, that you are only gathering the x component of the linear velocity in your function, so it may not be totally accurate if the ball bounces in a more vertical direction.

If you want it to be extremely accurate, you could gather both the x and y components and use vector math to get the velocity on the actual direction of the ball. Or, you could even use a post-collision listener and read the force that was generated by the collision (and check that if it was high enough, play the sound).

Brent

Hi @radim.simanek,

You may want to play the sound on the “began” phase instead of “ended”. However, this might not prevent the repeating sound, because the ball may be “breaking collision” at a very slight level (almost not visible to you, but visible to the physics engine).

One solution would be to surround the ball with another body element that is just slightly larger and set as a sensor (so it doesn’t cause any physical response). Then, on collision, you detect if that specific element collides, and you play the sound… but you don’t play the sound if the main body of the ball collides.

Hope this helps,

Brent

thanks for very fast response. I figured out this and it works reasonably well

local function ballBounce(  self, event ) local velocity = self:getLinearVelocity() if math.abs(velocity) \> 30 and ( event.phase == "ended" ) then audio.play(bounce) end end

Yes, that’s valid too. Note, however, that you are only gathering the x component of the linear velocity in your function, so it may not be totally accurate if the ball bounces in a more vertical direction.

If you want it to be extremely accurate, you could gather both the x and y components and use vector math to get the velocity on the actual direction of the ball. Or, you could even use a post-collision listener and read the force that was generated by the collision (and check that if it was high enough, play the sound).

Brent