How to get image to shake/rumble?

Hey everyone! I’m trying to make something that, upon the user taps the screen, an image rumbles, before moving back into position, sort of similar to a camera shake. However, I have no idea how to do it. How would I do this? Thanks in advance!

  • Harry

You have plenty of ways to approach this. Perhaps the easiest is via transitions and easing, something along the lines of this:

 

local shakeDone = true local shakeDistance = 50 local shakeTime = 50 local object = display.newRect( 240, 160, 180, 60 ) local function shakeReset() shakeDone = true end local function shakeEnd() transition.to( object, {time=shakeTime, x=object.x-shakeDistance, transition=easing.continuousLoop, onComplete=shakeReset}) end local function shake( event ) if event.phase == "ended" then if shakeDone then shakeDone = false transition.to( object, {time=shakeTime, x=object.x+shakeDistance, transition=easing.continuousLoop, onComplete=shakeEnd}) end end end local sensor = display.newRect( 240, 160, 480, 360 ) sensor.isVisible = false sensor.isHitTestable = true sensor:addEventListener( "touch", shake )

Try this:

local square = display.newRect(768,1024,100,100) local shakeEasing = function(currentTime, duration, startValue, targetDelta)     local shakeAmplitude = 100 -- maximum shake in pixels, at start of shake     local timeFactor = (duration-currentTime)/duration -- goes from 1 to 0 during the transition     local scaledShake =( timeFactor\*shakeAmplitude)+1 -- adding 1 prevents scaledShake from being less then 1 which would throw an error in the random code in the next line     local randomShake = math.random(scaledShake)     return startValue + randomShake - scaledShake\*0.5 -- the last part detracts half the possible max shake value so the shake is "symmetrical" instead of always being added at the same side end -- shakeEasing transition.to(square, {time = 1000, x = square.x, y = square.y, transition = shakeEasing})

You have plenty of ways to approach this. Perhaps the easiest is via transitions and easing, something along the lines of this:

 

local shakeDone = true local shakeDistance = 50 local shakeTime = 50 local object = display.newRect( 240, 160, 180, 60 ) local function shakeReset() shakeDone = true end local function shakeEnd() transition.to( object, {time=shakeTime, x=object.x-shakeDistance, transition=easing.continuousLoop, onComplete=shakeReset}) end local function shake( event ) if event.phase == "ended" then if shakeDone then shakeDone = false transition.to( object, {time=shakeTime, x=object.x+shakeDistance, transition=easing.continuousLoop, onComplete=shakeEnd}) end end end local sensor = display.newRect( 240, 160, 480, 360 ) sensor.isVisible = false sensor.isHitTestable = true sensor:addEventListener( "touch", shake )

Try this:

local square = display.newRect(768,1024,100,100) local shakeEasing = function(currentTime, duration, startValue, targetDelta)     local shakeAmplitude = 100 -- maximum shake in pixels, at start of shake     local timeFactor = (duration-currentTime)/duration -- goes from 1 to 0 during the transition     local scaledShake =( timeFactor\*shakeAmplitude)+1 -- adding 1 prevents scaledShake from being less then 1 which would throw an error in the random code in the next line     local randomShake = math.random(scaledShake)     return startValue + randomShake - scaledShake\*0.5 -- the last part detracts half the possible max shake value so the shake is "symmetrical" instead of always being added at the same side end -- shakeEasing transition.to(square, {time = 1000, x = square.x, y = square.y, transition = shakeEasing})