Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Debouncing collisions sound effects — Gideros Forum

Debouncing collisions sound effects

chipster123chipster123 Member
edited January 2012 in Game & application design
Any ideas on how to de-bounce a collision sound effect?
I'm giving control of some objects for a user to drag around. The objects are fixtures in the box2d system.
When the user drags one object into another a sound is played. When they collide, the object being pushed by the user pushes the other object too. Sometimes they bounce together rapidly as they push, making the collision sound repeatedly play fast and it winds up sounding like a rapid-fire noise.
Here is a code snipet
Scene =  gideros.class(Sprite)
function Scene:init()
...
 world:addEventListener(Event.BEGIN_CONTACT, self.onBeginContact, self)
...
 
 
function Scene:onBeginContact(event)
   local fixtureA = event.fixtureA
   local fixtureB = event.fixtureB
   local bodyA = fixtureA:getBody()
   local bodyB = fixtureB:getBody()
 
   --print("begin contact: "..bodyA.name.." "..bodyB.name)
   -- only make a sound if both objects have sound
   if bodyA.sound and bodyB.sound then
      bodyA.sound:play()
   end
end

Likes: fxone

+1 -1 (+1 / -0 )Share on Facebook

Comments

  • Set a flag to true on each body that the sound was played. Then on Event.END_CONTACT, reset that flag to false. And only play the sound when the flag is false.
  • atilimatilim Maintainer
    Good idea.

    One other option can be using Event.POST_SOLVE and check for event.maxImpulse > some_constant:
    local function onPostSolve(event)
        if event.maxImpulse > some_constant then
            sound:play()
        end
    end
  • @At Mike. Tested that and it is effectively the same. In a bounce situation, the END_CONTACT is immediately after the BEGIN_CONTACT, followed immediately by another BEGIN_CONTACT. The sequence happens so fast that still bounces the sound.

    I'll try the POST_SOLVE approach next. I'll report back with the results ...
  • The POST_SOLVE works and also gives the ability to make the collision volume proportional to the impact! I still had to limit the total number of sounds when there is a pile of objects being plowed through.
     
    function Scene3:onPostSolve(event)
       local fixtureA = event.fixtureA
       local fixtureB = event.fixtureB
       local bodyA = fixtureA:getBody()
       local bodyB = fixtureB:getBody()
     
       if event.maxImpulse > self.impactLimit and self.soundCount < self.soundLimit then
     
          -- only make a sound if both objects have sound
          if bodyA.sound and bodyB.sound then
    	 -- only play the sound of the smaller object
    	 local sound = nil
    	 -- make volume proportional to impact and limit to 1.0
    	 local volume = math.min(event.maxImpulse/50.0,1.0)
    	 if bodyA.size <= bodyB.size then
    	    sound = bodyA.sound
    	 else
    	    sound = bodyB.sound
    	 end
    	 self.soundCount = self.soundCount + 1
    	 local chan = sound:play()
    	 chan:setVolume(volume)
    	 chan:addEventListener(Event.SOUND_COMPLETE, self.endSound, self)
          end
       end
    end
     
    function Scene3:endSound()
       -- print "Sound finished"
       self.soundCount = self.soundCount -1
    end
    Thanks!

    Chip
  • atilimatilim Maintainer
    edited January 2012
    great!

    Also you may not play sounds with e.g. volume < 0.1.
Sign In or Register to comment.