summaryrefslogtreecommitdiff
path: root/sprite.gd
diff options
context:
space:
mode:
Diffstat (limited to 'sprite.gd')
-rw-r--r--sprite.gd96
1 files changed, 96 insertions, 0 deletions
diff --git a/sprite.gd b/sprite.gd
new file mode 100644
index 0000000..3bfc961
--- /dev/null
+++ b/sprite.gd
@@ -0,0 +1,96 @@
+class_name Sprite
+extends Node2D
+
+
+var sprite_data: SpriteResource
+var action_data: ActionFormat
+
+var current_action_idx := 0
+var current_frame := 0
+var current_start_time := 0.0
+var accumulator := 0.0
+
+var cache: Dictionary
+
+
+func _ready() -> void:
+ if not sprite_data or not action_data:
+ set_process(false)
+
+
+func load_file(path: String):
+ var basename = path.get_basename()
+
+ sprite_data = load("%s.tres" % basename)
+
+ var act = FileAccess.open("%s.act" % basename, FileAccess.READ)
+ action_data = ActionFormat.from_bytes(ByteStream.from_bytes(
+ act.get_buffer(act.get_length())
+ ))
+
+ if not sprite_data.files_exist():
+ sprite_data.save_to_file() # generate at "runtime"
+
+ set_process(true)
+ set_current_action(0)
+
+
+func set_current_action(idx: int):
+ current_action_idx = idx
+ current_frame = 0
+ current_start_time = 0
+ accumulator = 0
+
+ update(action_data.actions[current_action_idx].motions[current_frame].sprite_layers)
+
+
+func _process(delta: float) -> void:
+ var action = action_data.actions[current_action_idx]
+ var frame_time = ((action_data.frame_times[current_action_idx] * 24) / 1000)
+
+ accumulator += delta
+ if accumulator > current_start_time + frame_time:
+ var motion: ActionFormat.Motion = action.motions[current_frame]
+ update(motion.sprite_layers)
+
+ current_start_time = accumulator
+ current_frame += 1
+ if current_frame >= action.motions.size():
+ set_current_action(current_action_idx) # reset current action
+
+
+func update(sprite_layers: Array[ActionFormat.SpriteLayer]):
+ if not is_processing():
+ return
+
+ var has_different_layer_count = %SpriteLayers.get_child_count() != sprite_layers.size()
+
+ if has_different_layer_count:
+ for node in %SpriteLayers.get_children():
+ node.queue_free()
+
+ for idx in sprite_layers.size():
+ var sprite_layer = sprite_layers[idx]
+
+ var base_dir = sprite_data.filepath.substr(0, sprite_data.filepath.length() - 4) # cut off .spr
+ var image = load("%s/%s.png" % [base_dir, str(sprite_layer.sprite_index).pad_zeros(3)])
+
+ var sprite: Sprite2D
+ if has_different_layer_count:
+ sprite = Sprite2D.new()
+ sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
+ else:
+ sprite = %SpriteLayers.get_child(idx)
+
+ sprite.texture = image
+ sprite.position = sprite_layer.get_position()
+ sprite.self_modulate = sprite_layer.get_color()
+ sprite.scale = sprite_layer.get_scale()
+ sprite.rotation_degrees = sprite_layer.rotation_degrees
+ sprite.flip_h = sprite_layer.flip_h
+
+ # TODO: use sprite and action together to generate AnimatedSprite2D with SpriteFrame Resources?
+ # TODO: no. needs AnimationPlayer with config for different sprite positions in the animation
+
+ if has_different_layer_count:
+ %SpriteLayers.add_child(sprite)