Build Godot Resources
To make the player's animated_sprite, I needed to convert a large spritesheet into an animated sprite, with each animation split up.
It was much harder than I expected. Below is the code I did to create godot resources by code.
Getting the frames of each animation to create a separate spritesheet
extends AnimationPlayer
const PATH = "res://assets/Player/Sheets/"
# The sprite that contains the spritesheet
onready var chara := $"../Viewport/Character" as Sprite
var anim_names = get_animation_list()
for anim_name in anim_names:
var anim = get_animation(anim_name)
var idx = anim.find_track("Viewport/Character:frame")
var num = anim.track_get_key_count(idx)
var images: Array = []
for i in range(0, num):
var value = anim.track_get_key_value(idx, i)
var pos = Vector2((value % chara.hframes) * 64, (value / chara.hframes) * 64)
var size = Vector2.ONE * 64
var rec2 = Rect2(pos, size)
var new_image = chara.texture.get_data().get_rect(rec2)
images.append(new_image)
var final_image := Image.new()
final_image.crop(images.size() * 64, 64)
final_image.convert(Image.FORMAT_RGBA8)
final_image.fill(Color.transparent)
for i in images.size():
var image = images[i]
var rec2 = Rect2(Vector2.ZERO, Vector2.ONE * 64)
var dest = Vector2(i * 64, 0)
final_image.blit_rect(image, rec2, dest)
var _err = final_image.save_png(PATH + anim_name + ".png")
Adding the spritesheets to a animated sprite
func _create_player_sprite_frames():
for file_name in dir_contents(PATH):
file_name = file_name.get_basename()
frames.add_animation(file_name)
var image := Image.new()
image.convert(Image.FORMAT_RGBA8)
var _err := image.load(PATH + file_name + ".png")
var image_texture := ImageTexture.new()
image_texture.create_from_image(image, 0)
var size = image.get_size().x / 64
for i in size:
var atlas_texture := AtlasTexture.new()
atlas_texture.atlas = image_texture
atlas_texture.region = Rect2(i * 64, 0, 64, 64)
frames.add_frame(file_name, atlas_texture, i)
# The images are saved in raw in the file. it is BAD!
ResourceSaver.save("res://assets/Player/PlayerSpriteFrames.tres", frames)
func dir_contents(path) -> Array:
# Code is in the Godot docs of the File class
Convert the ressources images into a external resources
extends AnimatedSprite
const PATH := "res://assets/Player/Sheets/"
const PATH_RESOURCE := "res://assets/Player/PlayerSpriteFrames.tres"
var names = # Array of the names of every animation
func _remove_sub_ressource():
var file := File.new()
var _e := file.open(PATH_RESOURCE, File.READ)
var txt := file.get_as_text(true)
var txts := txt.split("\n")
var size := txts.size()
for i in range(size - 1, -1, -1):
if txts[i].find("[sub_resource type=\"Image\" id=") != -1:
for y in 8:
txts.remove(i)
file.close()
_e = file.open(PATH3, File.WRITE)
file.store_string(txts.join("\n"))
func _add_ext_resource():
var file := File.new()
var _e := file.open(PATH3, File.READ)
var txt := file.get_as_text(true)
var txts := txt.split("\n")
var size := txts.size()
var a = 0
for i in range(size - 1, -1, -1):
if txts[i].find("[sub_resource type=\"ImageTexture\" id=") != -1:
var value = int(txts[i].get_slice("=", 2).get_slice("]", 0))
for y in 4:
txts.remove(i)
txts[i] = "[ext_resource path=\"res://assets/Player/Sheets/%s.png\" type=\"Texture\" id=%s]" % [names[a], value]
a += 1
file.close()
_e = file.open(PATH4, File.WRITE)
file.store_string(txts.join("\n"))
Add a track in the animation player
for anim_name in anim_names:
var anim := get_animation(anim_name)
var idx := anim.add_track(TRACK_METHOD)
anim.track_insert_key(idx, 0, {
"args": [ anim_name ],
"method": "change_spritesheet"
})
anim.track_set_path(idx, NodePath("Viewport/AnimatedSprite"))