101 lines
3.6 KiB
GDScript
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
|