I couldn't find a built in screen-shake function, so I implemented the first bit o' logic I found on the internet. Since it's a pretty common feature in games these days, I figured I'd share it. Major features include:

• Variable duration, frequency, and amplitude.
• Maintains its own offset so it can be used in combination with other effects.

Since it extends Camera2D, all you have to do to use it is to instance this script instead of base Camera2D then call the shake function. I find that setting the duration, frequency, and amplitude to 0.2, 15, and 8 respectively gives a nice light shaking effect.

``````extends Camera2D

var _duration = 0.0
var _period_in_ms = 0.0
var _amplitude = 0.0
var _timer = 0.0
var _last_shook_timer = 0
var _previous_x = 0.0
var _previous_y = 0.0
var _last_offset = Vector2(0, 0)

set_process(true)

# Shake with decreasing intensity while there's time remaining.
func _process(delta):
# Only shake when there's shake time remaining.
if _timer == 0:
return
# Only shake on certain frames.
_last_shook_timer = _last_shook_timer + delta
# Be mathematically correct in the face of lag; usually only happens once.
while _last_shook_timer >= _period_in_ms:
_last_shook_timer = _last_shook_timer - _period_in_ms
# Lerp between [amplitude] and 0.0 intensity based on remaining shake time.
var intensity = _amplitude * (1 - ((_duration - _timer) / _duration))
# Noise calculation logic from http://jonny.morrill.me/blog/view/14
var new_x = rand_range(-1.0, 1.0)
var x_component = intensity * (_previous_x + (delta * (new_x - _previous_x)))
var new_y = rand_range(-1.0, 1.0)
var y_component = intensity * (_previous_y + (delta * (new_y - _previous_y)))
_previous_x = new_x
_previous_y = new_y
# Track how much we've moved the offset, as opposed to other effects.
var new_offset = Vector2(x_component, y_component)
set_offset(get_offset() - _last_offset + new_offset)
_last_offset = new_offset
# Reset the offset when we're done shaking.
_timer = _timer - delta
if _timer <= 0:
_timer = 0
set_offset(get_offset() - _last_offset)

# Kick off a new screenshake effect.
func shake(duration, frequency, amplitude):
# Initialize variables.
_duration = duration
_timer = duration
_period_in_ms = 1.0 / frequency
_amplitude = amplitude
_previous_x = rand_range(-1.0, 1.0)
_previous_y = rand_range(-1.0, 1.0)
# Reset previous offset, if any.
set_offset(get_offset() - _last_offset)
_last_offset = Vector2(0, 0)
``````
asked Feb 27, 2016 in Projects
Bookmarked! I'll try it later. Thanks for posting!

+1 vote

Thank you bro, I will use it for sure

answered Feb 28, 2016 by (46 points)