How to animate sprites in order

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By marcorexo

Hi,

I’m trying to animate 4 sprites in sequence:

  1. create a dictionary with keys numbering from 1 to 4 and values being the names of animated sprites:

sprites = {1:$sprite_top, 2:$sprite_right, 3:$sprite_bottom, 4:$sprite_left}

  1. Create a sequence vector ranging from 1…4

  2. I use a timer which calls a function that animates according to the sequence vector. The sprites animate at 1fps (3 frames) and the timer delay is set to 3s.

Code snippet:

var sequence
var flash_counter

    func _ready():
    	#used to count the number of sprites to flash
    	flash_counter = 0
    
    	timer = $Timer
        sequence = [1, 3, 2, 4]
    	#dictionary holding sprite sequence
    	sprites  = {1:$sprite_top, 2:$sprite_right, 3:$sprite_bottom, 4:$sprite_left}
    	pass
  func _draw():
        flash_sequence(flash_counter)
        pass
    
    
    func flash_sequence(number):
    	sprites[sequence[number]].play()
    	flash_counter += 1
    	timer.start()
    	pass
    
    func _on_Timer_timeout():
    	if(flash_counter != sequence.size()):
    		flash_sequence(flash_counter)
    	else:
    		timer.stop()
    	pass

The problem:
Though the function is called according to the timer and each sprite called in order, the sprites do not animate fully…not sure if there is some sort of discrepancy between the timer and sprite animation?

Why are you calling flash_sequence from _draw() AND in _on_Timer_timeout?
_draw() is called everytime the node visuals change, so it could be that your animation is being reset to the beginning because play() got called from two places at a time.

Also, you don’t need to write pass if the function is not empty.

Zylann | 2019-04-26 12:39

:bust_in_silhouette: Reply From: iron_weasel

As the zylann said in comment, draw is not something you should be using here. Try this:

func _ready():
    #used to count the number of sprites to flash
    flash_counter = 0
    timer = $Timer
    ordered_sprites = [$sprite_top, $sprite_bottom, $sprite_right, $sprite_left]
 
func _on_Timer_timeout():
    ordered_sprites[number].play()
    flash_counter += 1
    if flash_counter < ordered_sprites.size():
    	timer.start()

I cleaned up the code a little to make things easier to read, which should also make it easier to debug for you. But as long as the timer callback has been linked up then this should start playing each animation in an order defend by ordered_sprites with a delay defined by Timer.