Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

I need help with sound
Started by dodi_games Apr 28 2019 08:17 AM

11 replies to this topic
sound audio

Best Answer nick_sherman , 28 April 2019 - 09:35 AM

I usually just put a cooldown bool on objects, set it to true when a sound is played, set to false again after a short delay. Then in collision function only play a sound if cooldown is false on that object

[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 370 posts
  • Corona SDK

Hi all. I need help to solve this problem. The game is similar to a pinball game. The problem is that the sound of the ball is triggered simultaneously when it collides with two objects at the same time and the result is a stronger sound. In the picture you can better appreciate what I am describing. Any help on how to solve this?

 

 

Attached Files



[TOPIC: post.html]
#2

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,587 posts
  • Corona SDK

Can you make a small sample that demonstrates the physics interaction?  Then people can take a swing and helping implement the sound part.



[TOPIC: post.html]
#3

nick_sherman

[GLOBAL: userInfoPane.html]
nick_sherman
  • Corona Geek

  • 1,811 posts
  • Corona SDK

  Best Answer

I usually just put a cooldown bool on objects, set it to true when a sound is played, set to false again after a short delay. Then in collision function only play a sound if cooldown is false on that object
  • nick_sherman and dodi_games like this

[TOPIC: post.html]
#4

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,587 posts
  • Corona SDK

Question -  Are you saying:

 

1. You want only one sound to play no matter how many collisions occur in a short period?

 

- OR -

 

2. You want to play sound A for single collision, B for 'dual' collision, C ...?

 

 

If #1, then do what Nick says, or use/look at my sound lib which has a built-in limiter.

https://roaminggamer.github.io/RGDocs/pages/SSK2/libraries/soundMgr/#adding-sounds


-- Boing sound can only be played every 200 ms or less frequently
soundMgr.add( "boing", "sounds/sfx/boing.mp3", 
              { soundType = "effect", preload = true, minTweenTime = 200 } )

Note: Nick's solution is associated with the 'ball' so it makes more sense in this case.  My code would limit playing the 'boing' sound (shared) for all balls.  

 

 

If #2, that is something you'll need to use a delay for probably. i.e. Accumulate, then one frame later play sound.



[TOPIC: post.html]
#5

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 370 posts
  • Corona SDK

@roaminggamer 

 

What I want is that the sound is heard in each collision, regardless of when the collisions occur, they can be fractions of a second or up to 2 seconds (+, -). What I do not want is that if in a particular case the ball collides with two objects with similar physical properties and similar sound, the sound effect will be heard harder. What I think happens is that as the sound is not assigned to a specific channel and when it collides with two objects at the same time you hear the same sound twice causing the sound increase in volume because two channels are playing the same sound at the same time.



[TOPIC: post.html]
#6

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 370 posts
  • Corona SDK

I am trying to attach a .rar to show the example but I do not have permission to upload this type of files.  Any suggestions?



[TOPIC: post.html]
#7

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 370 posts
  • Corona SDK

I think it's simpler this way. Just copy this code and paste it in a new project main.lua and add any sound with the name boing.

 

 

-- sound test to the forums
local centerX = display.contentCenterX
local centerY = display.contentCenterY
local obt
local boing = audio.loadSound("boing.wav")
local physics = require( "physics" )
physics.start()
--collision
local function onLocalCollision( self, event )
  if ( event.phase == "began" ) then
    if (self.id == "ball" and event.other.id == "bars") then
      audio.play( boing )
      display.remove( obj[1])
    end
  end
end
--ball
local ballColor = { 0, 128, 0 }
local ball = display.newCircle( centerX, centerY-400, 30 )  --300
ball.fill = ballColor
ball.id = "ball"
physics.addBody( ball, { density=0.8, friction=1.0, bounce=0.5, radius=30 } )
ball.collision = onLocalCollision
ball:addEventListener( "collision", ball )
--objects
obj = {}
local numOfObj = 3
for i = 1, numOfObj do
  obj[i] = display.newRect( 0, 0, 30, 50 )
  obj[i]:setFillColor( 255, 0, 0 )
  obj[i].id = "bars"
  physics.addBody( obj[i], "static", { friction=0, bounce=0 } )
end
  obj[1].x = centerX
  obj[1].y = centerY-65
  obj[2].x = centerX-25
  obj[2].y = centerY+75
  obj[3].x = centerX+25
  obj[3].y = centerY+75


[TOPIC: post.html]
#8

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 2,110 posts
  • Corona SDK

Geesh... just have 2 sounds. 1 for a single hit and another for a dual hit.

 

(Corona will not play the same sound twice if the first sound is currently playing)



[TOPIC: post.html]
#9

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 370 posts
  • Corona SDK

Thanks @SGS but 2 sounds do not resolve my problem... Is a pinball like game... At least it would need 45 equal sounds but with different names for each dual hit collision.

[TOPIC: post.html]
#10

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,587 posts
  • Corona SDK

@Dodi - That site gets flagged as unsafe for me. 

 

In the future I suggest using a reputable download source like Github (you can create a free account) or dropbox (again free).


  • dodi_games likes this

[TOPIC: post.html]
#11

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,587 posts
  • Corona SDK

Yeah, you can't really do that.  The sounds won't sum. i.e. simultaneous sounds are not additive

 

The best you can do is defer the sound and play just one sound louder, but you'll have to start at something below 1.0 to increase.

 

https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2019/04/dodi_sound.zip

io.output():setvbuf("no")
display.setStatusBar(display.HiddenStatusBar)
-- =====================================================
--require "ssk2.loadSSK"
--_G.ssk.init( { measure = false } )
--ssk.meters.create_fps(true)
--ssk.meters.create_mem(true)
--ssk.misc.enableScreenshotHelper("s") 
-- =====================================================
local cx     = display.contentCenterX
local cy     = display.contentCenterY
local fullw  = display.actualContentWidth
local fullh  = display.actualContentHeight
local left   = cx - fullw/2
local right  = cx + fullw/2
local top    = cy - fullh/2
local bottom = cy + fullh/2
-- == Uncomment following lines if you need  physics
local physics = require "physics"
physics.start()
physics.setGravity(0,10)
physics.setDrawMode("hybrid")

-- =====================================================
-- YOUR CODE BELOW
-- =====================================================
-- sound test to the forums
local centerX = display.contentCenterX
local centerY = display.contentCenterY
local obt
local boing = audio.loadSound("boing.mp3")
local physics = require( "physics" )
physics.start()

local baseVolume = 0.25

local function onTimer( self )
   local channel = audio.findFreeChannel( 1 )
   self.boing = (self.boing or 1)
   print( "BOING ", baseVolume * self.boing )
   audio.setVolume( baseVolume * self.boing, { channel = channel } ) -- set the volume on channel 1
   audio.play( boing, { channel = channel } )
   self.boingTimer = nil
   self.boing = 1
end

--collision
local function onLocalCollision( self, event )
  if ( event.phase == "began" ) then
    if (self.id == "ball" and event.other.id == "bars") then
      --audio.play( boing )
      self.boing = (self.boing) and (self.boing + 1) or 1
      if( self.boingTimer ) then 
      	timer.cancel(self.boingTimer)      	
      end
      self.boingTimer = timer.performWithDelay( 1,self )
      display.remove( obj[1])
    end
  end
end
--ball
local ballColor = { 0, 128, 0 }
local ball = display.newCircle( centerX, centerY-400, 30 )  --300
ball.fill = ballColor
ball.id = "ball"
physics.addBody( ball, { density=0.8, friction=1.0, bounce=0.5, radius=30 } )
ball.collision = onLocalCollision
ball:addEventListener( "collision", ball )

ball.timer = onTimer

--objects
obj = {}
local numOfObj = 3
for i = 1, numOfObj do
  obj[i] = display.newRect( 0, 0, 30, 50 )
  obj[i]:setFillColor( 255, 0, 0 )
  obj[i].id = "bars"
  physics.addBody( obj[i], "static", { friction=0, bounce=0 } )
end
  obj[1].x = centerX
  obj[1].y = centerY-65
  obj[2].x = centerX-25
  obj[2].y = centerY+75
  obj[3].x = centerX+25
  obj[3].y = centerY+75

  • dodi_games likes this

[TOPIC: post.html]
#12

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 370 posts
  • Corona SDK

I want to thank all those who contributed their help. After playing hours with the roaminggamer's code, I return to the topic and read well the comment of nick_sherman. I have added this function and the problem has been solved. Here I leave the code for those who want to try. Apparently the physical objects do not collide at the same time in any situation, there is always a small delay.

 

 

-- sound test to the forums
local centerX = display.contentCenterX
local centerY = display.contentCenterY
local obt
local boing = audio.loadSound("boing.wav")
local soundValue = true
local physics = require( "physics" )
physics.start()

--prevent boing sound from being heard twice-------------------------------
local function playBoingSound( event )
  if (soundValue == true) then
    audio.play( boing )
    soundValue = false
  end
  timer.performWithDelay(10,
    function()
      soundValue = true
    end
  )
end
-----------------------------------------------------------------------------

--collision
local function onLocalCollision( self, event )
  if ( event.phase == "began" ) then
    if (self.id == "ball" and event.other.id == "bars") then
      playBoingSound() --audio.play( boing )------------------------------function added
      display.remove( obj[1])
    end
  end
end
--ball
local ballColor = { 0, 128, 0 }
local ball = display.newCircle( centerX, centerY-400, 30 )  --300
ball.fill = ballColor
ball.id = "ball"
physics.addBody( ball, { density=0.8, friction=1.0, bounce=0.5, radius=30 } )
ball.collision = onLocalCollision
ball:addEventListener( "collision", ball )
--objects
obj = {}
local numOfObj = 3
for i = 1, numOfObj do
  obj[i] = display.newRect( 0, 0, 30, 50 )
  obj[i]:setFillColor( 255, 0, 0 )
  obj[i].id = "bars"
  physics.addBody( obj[i], "static", { friction=0, bounce=0 } )
end
  obj[1].x = centerX
  obj[1].y = centerY-65
  obj[2].x = centerX-25
  obj[2].y = centerY+75
  obj[3].x = centerX+25
  obj[3].y = centerY+75



[topic_controls]
[/topic_controls]

Also tagged with one or more of these keywords: sound, audio