0 votes

I am using OpenSimplexNoise.get_noise_2d() to achieve screenshake.

It works like this. My camera has the following variables: trauma, max_offset_x, max_offset_y.

Each frame, I calculate offset.x = trauma * max_offset_x * smooth_noise.get_noise2d(elapsed_game_time, elapsed_game_time).

Similarly for offset.y.

I decrement trauma using a Timer. As trauma decrements, the screenshake slows. When trauma == 0, the shake stops.

Moving through the smooth noise makes the camera shake smoothly, rather than discretely. This works really well.

The problem is that when I initially set a new trauma value to start the shake, I'd like to be able to set the initial direction of the shake. For example, I may want the camera to initially move to the right, before continuing its shake moving left.

How can I alter my system to allow for a specification of original direction?

extends Camera2D

# references below
onready var timer = get_node("Timer")

# attribues
var trauma_y = 0 setget set_trauma_y
var trauma_x = 0 setget set_trauma_x
var shake_x = 0
var shake_y = 0
var max_offset = 8
var smooth_noise
var constant_trauma = false

func set_trauma_y(value):
    trauma_y = value
    if timer.is_stopped():
        timer.start()
    set_physics_process(true)

func set_trauma_x(value):
    trauma_x = value
    if timer.is_stopped():
        timer.start()
    set_physics_process(true)

func _ready():
    # creating noise
    smooth_noise = OpenSimplexNoise.new()
    smooth_noise.seed = randi()
    smooth_noise.octaves = 4
    smooth_noise.period = 0.1
    #smooth_noise.persistence = 0.8

func _physics_process(delta):
    # shake is a function of trauma
    shake_y = trauma_y * trauma_y
    shake_x = trauma_x * trauma_x

    # use perlin noise for screen shake -- vertical
    offset.y = max_offset * shake_y * smooth_noise.get_noise_2d(Globals.now, Globals.now) * 10

    # use perlin noise for screen shake -- horizontal
    offset.x = max_offset * shake_x * smooth_noise.get_noise_2d(Globals.now * 2, Globals.now * 2) * 10

    if trauma_y == 0 and trauma_x == 0:
        timer.stop()
        set_physics_process(false)

func _on_Timer_timeout():
    trauma_y -= 0.025
    if trauma_y < 0:
        trauma_y = 0

    trauma_x -= 0.025
    if trauma_x < 0:
        trauma_x = 0
asked Jun 9, 2019 in Engine by Diet Estus (1,504 points)
edited Jun 9, 2019 by Diet Estus

Would you mind share the script/node? I'll see if I can help.

Perhaps if you want direction in your screenshake, you shouldn't use noise at all. This is what I expect to get from a noise-based screenshake algorithm: YouTube video.

Updated to share the code. That talk is where I learned the technique, haha. Maybe I'll have to scrap it if I want an initial direction. But I was hoping to build it in some way.

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.