FunkPanion/scripts/SpritesheetParser.gd
2024-11-23 14:36:52 -06:00

101 lines
3.6 KiB
GDScript

class_name SpritesheetParser
var spritesheet
var max_dimensions : Vector2i
var _parser = XMLParser.new()
var _filename_regex = RegEx.new()
func parse_spritesheet(path):
var animations = {}
max_dimensions = Vector2i(0, 0)
_parser.open(path)
_filename_regex.compile("^(.+?)(\\d{1,4})$")
while _parser.read() != ERR_FILE_EOF:
if _parser.get_node_type() != XMLParser.NODE_ELEMENT:
continue
var node_name = _parser.get_node_name()
if node_name != "SubTexture":
continue
var frame_search = _filename_regex.search(_parser.get_named_attribute_value_safe("name"))
var frame_name = frame_search.get_string(1)
var frame_no = frame_search.get_string(2).to_int()
var frame_x = _parser.get_named_attribute_value_safe("x")
var frame_y = _parser.get_named_attribute_value_safe("y")
var frame_width = _parser.get_named_attribute_value_safe("width")
var frame_height = _parser.get_named_attribute_value_safe("height")
var frame_frame_x = _parser.get_named_attribute_value_safe("frameX")
var frame_frame_y = _parser.get_named_attribute_value_safe("frameY")
var frame_frame_width = _parser.get_named_attribute_value_safe("frameWidth")
var frame_frame_height = _parser.get_named_attribute_value_safe("frameHeight")
if not animations.has(frame_name):
animations[frame_name] = []
var array = animations[frame_name]
var frame_data = {}
if frame_x.is_valid_int() and frame_y.is_valid_int():
frame_data.pos = Vector2i(frame_x.to_int(), frame_y.to_int())
else:
frame_data.pos = Vector2i.ZERO
if frame_width.is_valid_int() and frame_height.is_valid_int():
frame_data.size = Vector2i(frame_width.to_int(), frame_height.to_int())
if frame_width.to_int() > max_dimensions.x:
max_dimensions.x = frame_width.to_int()
if frame_height.to_int() > max_dimensions.y:
max_dimensions.y = frame_height.to_int()
else:
frame_data.size = Vector2i.ZERO
if frame_frame_x.is_valid_int() and frame_frame_y.is_valid_int():
frame_data.frame_pos = Vector2i(frame_frame_x.to_int(), frame_frame_y.to_int())
else:
frame_data.frame_pos = Vector2i.ZERO
if frame_frame_width.is_valid_int() and frame_frame_height.is_valid_int():
frame_data.frame_size = Vector2i(frame_frame_width.to_int(), frame_frame_height.to_int())
if frame_frame_width.to_int() > max_dimensions.x:
max_dimensions.x = frame_frame_width.to_int()
if frame_frame_height.to_int() > max_dimensions.y:
max_dimensions.y = frame_frame_height.to_int()
else:
frame_data.frame_size = frame_data.size
if frame_no >= array.size():
array.resize(frame_no + 1)
array[frame_no] = frame_data
for animation in animations:
var anim_frames: Array = animations[animation]
while anim_frames.has(null):
anim_frames.erase(null)
spritesheet = animations
func get_props_of_animation_frame(anim:String, frameno:int):
var anim_frames = spritesheet[anim]
frameno = clamp(frameno, 0, anim_frames.size() - 1)
var frame = anim_frames[frameno]
return {
region = Rect2(frame.pos, frame.size),
margin = Rect2(-frame.frame_pos, frame.frame_size - frame.size)
}
static func load_image(path: String):
if path.begins_with('res'):
return load(path)
else:
var file = FileAccess.open(path, FileAccess.READ)
if FileAccess.get_open_error() != OK:
print(str("Could not load image at: ",path))
return
var buffer = file.get_buffer(file.get_length())
var image = Image.new()
var error = image.load_png_from_buffer(buffer)
if error != OK:
print(str("Could not load image at: ",path," with error: ",error))
return
var texture = ImageTexture.create_from_image(image)
return texture