Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Another Shake — Gideros Forum

Another Shake

bowerandybowerandy Guru
edited May 2013 in Code snippets
Folks,

I wasn't too happy with some of the other "shake" examples that I'd seen so here is another attempt that based around some Flash ActrionScript that I found here:

http://stackoverflow.com/a/13714372/1691412

This is what it looks like:


And here's the code:
function Sprite:shake(duration, distance, angle, ease, frequency)
 
	local function outExponential(ratio)
		-- Just in case easing.lua is not available
		if ratio == 1 then return 1 end
		return 1-math.pow(2, -10 * ratio)
	end
 
	if self._shakeTimer then
		-- Kill any existing shake
		local e=Event.new(Event.TIMER_COMPLETE)
		self._shakeTimer:dispatchEvent(e)
	end
 
	duration=duration or 0.5
	distance=distance or 30
	frequency=frequency or 100
	angle = angle or 0
	ease=ease or outExponential
 
	local shakes=math.floor(duration*frequency)
	local shakeTimer=Timer.new(1000/frequency, shakes)
	local startX, startY=self:getPosition()
	local startRot=self:getRotation()
	local count=0
 
	local function shakeUpdate(e)
		count=count+1
		local amplitude=1-ease(count/shakes)
		local x=startX+(-distance / 2 + math.random()*distance)*amplitude
		local y=startY+(-distance / 2 + math.random()*distance)*amplitude
		local rot=startRot+(-angle / 2 + math.random()*angle)*amplitude
		self:setPosition(x, y)
		self:setRotation(rot)
	end
 
	local function shakeComplete(e)
		self:setPosition(startX, startY)
		self:setRotation(startRot)
		shakeTimer:removeEventListener(Event.TIMER, shakeUpdate)
		shakeTimer:removeEventListener(Event.TIMER_COMPLETE, shakeComplete)
		self._shakeTimer=nil
	end
 
	shakeTimer:addEventListener(Event.TIMER, shakeUpdate)
	shakeTimer:addEventListener(Event.TIMER_COMPLETE, shakeComplete)
	shakeTimer:start()
	self._shakeTimer=shakeTimer
end
 
-- Shake example
local boing=Sound.new("Boing.wav")
application:setBackgroundColor(0x76BAF1)
 
local button=Bitmap.new(Texture.new("HelpButton.png"))
stage:addChild(button)
button:setAnchorPoint(0.5, 0.5)
button:setPosition(240, 160)
 
button:addEventListener(Event.TOUCHES_BEGIN, 
	function() 
		boing:play()
		button:shake(0.8, 50, 10)
	end)
The default parameters give a reasonable shake but you can obviously tailor them as desired. It's probably best not to set a shake angle unless the object you are shaking has an anchor point set to its centre.

best regards
+1 -1 (+9 / -0 )Share on Facebook

Comments

  • Apollo14Apollo14 Member
    edited September 2019
    Hey guys! Recently I was watching one interesting youtube video and became curious about shaking effects. And I've found this topic.

    The Sprite:shake() function as described here works perfectly well and it's extremely useful! Let's add more juice to our games :D

    P.s. Btw we can shake whole stage as well (since stage is also a Sprite)
    stage:shake(4,50,10)

    And one little question:
    Sprites do shake around anchorpoint, which is usually '0,0' and sometimes it's inconvenient to centrify it to '0.5,0.5'.
    Are there any workaround to shake Sprite around its center without changing its anchorpoint to '0.5,0.5'?

    Cheers!

    Likes: MoKaLux

    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
    “The more you do coding stuff, the better you get at it.” - Aristotle (322 BC)
    +1 -1 (+1 / -0 )Share on Facebook
  • just what I was looking for, thank you @Apollo14
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
Sign In or Register to comment.