#Sprite shake with tween

25 messages · Page 1 of 1 (latest)

little otter
#

How can I shake a sprite in place? I thought about using a tween but randf_range is only called once, meaning that the tween just moves between 2 points instead of shaking

var tween := create_tween().set_loops()
var amount := 1.0
tween.tween_property($Sprite2D, "position", Vector2(randf_range(-amount, amount), randf_range(-amount, amount)), 0.05)
obsidian igloo
#

if you want shaking effect, i think animation or this is more appropriate:

if is_shaking:
    $Sprite2D.position = Vector2(randf_range(-amount, amount), randf_range(-amount, amount))```

to use tween in this case, you can just call tween_property multiple times
```go
func _ready():
    var amount = 20
    var duration = 1
    var one_loop_time = 0.05
    
    var tween = get_tree().create_tween()
    
    while duration > 0:
        var shake_vector = Vector2(randf_range(-amount, amount), randf_range(-amount, amount))
        duration -= one_loop_time
        tween.tween_property($Sprite2D, "position", position + shake_vector, one_loop_time)
    
    tween.tween_property($Sprite2D, "position", position, one_loop_time)```
little otter
obsidian igloo
#

first example should be put in _process function and is_shaking should be managed properly

#

Did you put randf_range line inside the while loop?

little otter
#

also the benefit of using a tween here is controlling the time between each shake

obsidian igloo
#

Can you give me your code? Cause it worked in my computer

little otter
#

wait no, i just used yours

#

hold on

little otter
# obsidian igloo Can you give me your code? Cause it worked in my computer
func shake() -> void:
    var tween := create_tween()
    var amount := 1.0
    var duration := 1
    var one_loop_time := 0.05

    while duration > 0:
        var shake_vector = Vector2(randf_range(-amount, amount), randf_range(-amount, amount))
        duration -= one_loop_time
        tween.tween_property($Sprite2D, "position", position + shake_vector, one_loop_time)
    tween.tween_property($Sprite2D, "position", position, one_loop_time)
#

I don't want it to shake only once

#

or rather

#

i want it to shake forever once i call shake()

#

and i can't just call while true because the game freezes if i do that

obsidian igloo
#

can you try this?

    var amount := 20
    var duration := 1
    var one_loop_time := 0.05
    
    var tween := get_tree().create_tween()
    
    while duration > 0:
        var shake_vector = Vector2(randf_range(-amount, amount), randf_range(-amount, amount))
        duration -= one_loop_time
        tween.tween_property($Sprite2D, "position", shake_vector, one_loop_time)
    
    tween.tween_property($Sprite2D, "position", Vector2.ZERO, one_loop_time)
    
    tween.connect("finished", shake)```
#

last line will make it shakes forever

#

and position should not be added at tween_property parameter (sorry my bad)

#

works like this in my computer

#

also you can remove while loop like this:

func shake() -> void:
    var amount := 20
    var one_loop_time := 0.05
    var tween := get_tree().create_tween()
    var shake_vector := Vector2(randf_range(-amount, amount), randf_range(-amount, amount))
    
    tween.tween_property($Sprite2D, "position", shake_vector, one_loop_time)
    
    tween.connect("finished", shake)```
#

hope it helps 🙂

little otter
obsidian igloo
#

create interrupt shake variable like this:


func interrupt_shake() -> void:
    _interrupt_shake = true

func shake() -> void:
    var amount := 20
    var one_loop_time := 0.05
    var tween := get_tree().create_tween()
    var shake_vector := Vector2(randf_range(-amount, amount), randf_range(-amount, amount))
    
    tween.tween_property($Sprite2D, "position", shake_vector, one_loop_time)
    
    if _interrupt_shake:
        _interrupt_shake = false
        tween.tween_property($Sprite2D, "position", Vector2(0, 0), one_loop_time)
        return
    
    tween.connect("finished", shake)```
#

call interrupt_shake() where you want to stop the shaking