Sprite 'explosion' adding animations to AnimationPlayer node using GDScript 4.2

I needed to make my sprites explode by slicing them in rectangles and spreading them away. As I did not find an example or tutorial for Godot 4.2 finally I managed to create my own method. I’m sharing it to the community in case some one else may need it or may be has a better way to do it.

Node2D
→ Sprite2D
→ AnimationPlayer

Script for Node2D:

extends Node2D

var X_CUT = 4 	# | |      |
				# | | ...  |
				# v v      v

var Y_CUT = 4# ---->
				# ---->
				# ---->
				# ...
				# ---->

var library : AnimationLibrary  
var displacement : Vector2

# To be adjusted as needed
var x_scale = 250 
var y_scale = 150

@onready var sprite = $Sprite2D
@onready var animation_player = $AnimationPlayer

func _ready():
	
	# Create an animation library, an animation add it to the animation library 
	# and add the animation library to the animation player node
	library=AnimationLibrary.new()
	var anim=Animation.new()
	library.add_animation("explode",anim)
	animation_player.add_animation_library("Mylib",library)
 
	# Calculate displacement to set the center of the explosion in the position of the sprite
	displacement = -Vector2((X_CUT)*x_scale/2.0-x_scale/2.0,(Y_CUT)*y_scale/2.0-y_scale/2.0)

	# Add a track to make the sprite invisible before the explosion
	var track0 = anim.add_track(Animation.TYPE_VALUE)
	var sprite_path = sprite.name+":visible"
	anim.track_set_path(track0,sprite_path)
	anim.track_insert_key(track0, 0.0, false, 1.0)
			
	# for each (x,y) frame of the sprite add its corresponding animation track and set its values
	var idx = 0 # Index of the frames in which the sprite will be sliced (0 -> X_CUT*Y_CUT)
	for i in range(Y_CUT):
		for j in range(X_CUT):
			
			var fragmt_sprite = Sprite2D.new()
			fragmt_sprite.set_texture(sprite.texture)
			#fragmt_sprite.scale = $Sprite.scale
			fragmt_sprite.set_vframes(Y_CUT)
			fragmt_sprite.set_hframes(X_CUT)
			fragmt_sprite.set_frame(idx)
			add_child(fragmt_sprite)
			
			var track1 = anim.add_track(Animation.TYPE_VALUE)
			var fragmt_sprite_path = fragmt_sprite.name+":position"
			anim.track_set_path(track1,fragmt_sprite_path)
			anim.track_insert_key(track1, 0.0, sprite.position,0.3)
			
			# Target position calculation
			var new_pos =  Vector2(j*x_scale,i*y_scale)+sprite.position+displacement
			anim.track_insert_key(track1, 0.9, new_pos, 4.0)
			
			anim.value_track_set_update_mode(track1,Animation.UPDATE_CONTINUOUS)
			
			idx += 1

func _process(_delta):
	if Input.is_action_just_pressed("up"):
		animation_player.play("Mylib/explode")
		print("Explosion...")
2 Likes

BTW. It is not necessary to create a new animation library, you can use the default [Global]:

library=$AnimationPlayer.get_animation_library("")