2020-06-12 02:27:21 +03:00
|
|
|
extends Node2D
|
|
|
|
|
2023-03-23 18:25:33 +05:00
|
|
|
enum Mode { TIMELINE, SPRITESHEET }
|
2023-04-19 20:35:27 +03:00
|
|
|
var mode: int = Mode.TIMELINE
|
2023-03-23 18:25:33 +05:00
|
|
|
|
2023-04-19 20:35:27 +03:00
|
|
|
var h_frames := 1
|
|
|
|
var v_frames := 1
|
|
|
|
var start_sprite_sheet_frame := 1
|
|
|
|
var end_sprite_sheet_frame := 1
|
|
|
|
var sprite_frames := []
|
|
|
|
var frame_index := 0
|
2023-03-23 18:25:33 +05:00
|
|
|
|
2023-04-19 20:35:27 +03:00
|
|
|
onready var animation_timer := $AnimationTimer as Timer
|
|
|
|
onready var transparent_checker = get_parent().get_node("TransparentChecker") as ColorRect
|
2020-06-12 02:27:21 +03:00
|
|
|
|
2020-08-02 00:59:00 +03:00
|
|
|
|
2020-06-12 02:27:21 +03:00
|
|
|
func _draw() -> void:
|
2021-11-25 14:48:30 +02:00
|
|
|
var current_project: Project = Global.current_project
|
2023-03-23 18:25:33 +05:00
|
|
|
match mode:
|
|
|
|
Mode.TIMELINE:
|
2023-04-19 20:35:27 +03:00
|
|
|
var modulate_color := Color.white
|
|
|
|
if frame_index >= current_project.frames.size():
|
|
|
|
frame_index = current_project.current_frame
|
2023-03-23 18:25:33 +05:00
|
|
|
if animation_timer.is_stopped():
|
2023-04-19 20:35:27 +03:00
|
|
|
frame_index = current_project.current_frame
|
|
|
|
var frame: Frame = current_project.frames[frame_index]
|
|
|
|
animation_timer.wait_time = frame.duration * (1 / current_project.fps)
|
|
|
|
var current_cels: Array = frame.cels
|
2023-03-23 18:25:33 +05:00
|
|
|
|
|
|
|
# Draw current frame layers
|
|
|
|
for i in range(current_cels.size()):
|
2023-04-19 20:35:27 +03:00
|
|
|
var cel: BaseCel = current_cels[i]
|
|
|
|
if cel is GroupCel:
|
2023-03-23 18:25:33 +05:00
|
|
|
continue
|
2023-04-19 20:35:27 +03:00
|
|
|
modulate_color = Color(1, 1, 1, cel.opacity)
|
2023-03-23 18:25:33 +05:00
|
|
|
if (
|
|
|
|
i < current_project.layers.size()
|
|
|
|
and current_project.layers[i].is_visible_in_hierarchy()
|
|
|
|
):
|
2023-04-19 20:35:27 +03:00
|
|
|
draw_texture(cel.image_texture, Vector2.ZERO, modulate_color)
|
2023-03-23 18:25:33 +05:00
|
|
|
Mode.SPRITESHEET:
|
2023-04-19 20:35:27 +03:00
|
|
|
var texture_to_draw: ImageTexture
|
|
|
|
var target_frame: Frame = current_project.frames[current_project.current_frame]
|
|
|
|
var frame_image := Image.new()
|
2023-03-23 18:25:33 +05:00
|
|
|
frame_image.create(
|
|
|
|
current_project.size.x, current_project.size.y, false, Image.FORMAT_RGBA8
|
|
|
|
)
|
|
|
|
Export.blend_all_layers(frame_image, target_frame)
|
|
|
|
sprite_frames = split_spritesheet(frame_image, h_frames, v_frames)
|
|
|
|
|
|
|
|
# limit start and end
|
|
|
|
if end_sprite_sheet_frame > sprite_frames.size():
|
|
|
|
end_sprite_sheet_frame = sprite_frames.size()
|
|
|
|
if start_sprite_sheet_frame < 0:
|
|
|
|
start_sprite_sheet_frame = 0
|
|
|
|
# reset frame if required
|
2023-04-19 20:35:27 +03:00
|
|
|
if frame_index >= end_sprite_sheet_frame:
|
|
|
|
frame_index = start_sprite_sheet_frame - 1
|
|
|
|
texture_to_draw = sprite_frames[frame_index]
|
|
|
|
draw_texture(texture_to_draw, Vector2.ZERO)
|
2023-03-23 18:25:33 +05:00
|
|
|
|
2023-04-19 20:35:27 +03:00
|
|
|
var rect := Rect2(Vector2.ZERO, texture_to_draw.get_data().get_size())
|
|
|
|
transparent_checker.fit_rect(rect)
|
2020-08-02 00:59:00 +03:00
|
|
|
|
|
|
|
|
|
|
|
func _on_AnimationTimer_timeout() -> void:
|
2023-03-23 18:25:33 +05:00
|
|
|
match mode:
|
|
|
|
Mode.TIMELINE:
|
|
|
|
var current_project: Project = Global.current_project
|
2023-04-19 20:35:27 +03:00
|
|
|
var first_frame := 0
|
|
|
|
var last_frame: int = current_project.frames.size() - 1
|
2022-07-21 22:26:01 +03:00
|
|
|
|
2023-03-23 18:25:33 +05:00
|
|
|
if Global.play_only_tags:
|
|
|
|
for tag in current_project.animation_tags:
|
|
|
|
if (
|
|
|
|
current_project.current_frame + 1 >= tag.from
|
|
|
|
&& current_project.current_frame + 1 <= tag.to
|
|
|
|
):
|
|
|
|
first_frame = tag.from - 1
|
|
|
|
last_frame = min(current_project.frames.size() - 1, tag.to - 1)
|
2022-07-21 22:26:01 +03:00
|
|
|
|
2023-04-19 20:35:27 +03:00
|
|
|
if frame_index < last_frame:
|
|
|
|
frame_index += 1
|
2023-03-23 18:25:33 +05:00
|
|
|
else:
|
2023-04-19 20:35:27 +03:00
|
|
|
frame_index = first_frame
|
2020-10-19 16:57:40 +02:00
|
|
|
|
2023-04-19 20:35:27 +03:00
|
|
|
animation_timer.wait_time = (
|
|
|
|
current_project.frames[frame_index].duration
|
|
|
|
* (1 / current_project.fps)
|
2023-03-23 18:25:33 +05:00
|
|
|
)
|
|
|
|
|
|
|
|
Mode.SPRITESHEET:
|
2023-04-19 20:35:27 +03:00
|
|
|
frame_index += 1
|
|
|
|
animation_timer.wait_time = (1 / Global.current_project.fps)
|
|
|
|
animation_timer.set_one_shot(true)
|
|
|
|
animation_timer.start()
|
2020-08-02 00:59:00 +03:00
|
|
|
update()
|
2023-03-23 18:25:33 +05:00
|
|
|
|
|
|
|
|
|
|
|
func split_spritesheet(image: Image, horiz: int, vert: int) -> Array:
|
2023-04-19 20:35:27 +03:00
|
|
|
var result := []
|
2023-03-23 18:25:33 +05:00
|
|
|
horiz = min(horiz, image.get_size().x)
|
|
|
|
vert = min(vert, image.get_size().y)
|
|
|
|
var frame_width := image.get_size().x / horiz
|
|
|
|
var frame_height := image.get_size().y / vert
|
|
|
|
for yy in range(vert):
|
|
|
|
for xx in range(horiz):
|
|
|
|
var tex := ImageTexture.new()
|
|
|
|
var cropped_image := Image.new()
|
2023-04-19 20:35:27 +03:00
|
|
|
var rect := Rect2(frame_width * xx, frame_height * yy, frame_width, frame_height)
|
|
|
|
cropped_image = image.get_rect(rect)
|
2023-03-23 18:25:33 +05:00
|
|
|
cropped_image.convert(Image.FORMAT_RGBA8)
|
|
|
|
tex.create_from_image(cropped_image, 0)
|
|
|
|
result.append(tex)
|
|
|
|
return result
|