2022-01-13 05:24:03 +01:00
enum SPRITE_STACK {
horizontal,
vertical,
grid
}
enum SPRITE_ANIM_GROUP {
animation,
all_sprites
}
2023-02-28 09:43:01 +01:00
function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
2023-01-25 06:49:00 +01:00
name = "Render Spritesheet";
2022-12-23 04:45:52 +01:00
anim_drawn = array_create(ANIMATOR.frames_total + 1, false);
2022-01-13 05:24:03 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 0] = nodeValue("Sprites", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone);
2022-01-13 05:24:03 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 1] = nodeValue("Sprite set", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Animation", "Sprite array" ])
.rejectArray();
2022-01-13 05:24:03 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 2] = nodeValue("Frame step", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1, "Number of frames until next sprite. Can be seen as (Step - 1) frame skip.")
.rejectArray();
2022-01-13 05:24:03 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 3] = nodeValue("Packing type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Horizontal", "Vertical", "Grid" ])
.rejectArray();
2022-01-13 05:24:03 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 4] = nodeValue("Grid column", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 4)
.rejectArray();
2022-01-13 05:24:03 +01:00
2023-02-14 05:32:32 +01:00
inputs[| 5] = nodeValue("Alignment", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
.setDisplay(VALUE_DISPLAY.enum_button, [ "First", "Middle", "Last" ])
.rejectArray();
2022-01-13 05:24:03 +01:00
2023-03-05 07:16:44 +01:00
inputs[| 6] = nodeValue("Spacing", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0);
inputs[| 7] = nodeValue("Padding", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0, 0, 0 ])
.setDisplay(VALUE_DISPLAY.padding)
2023-02-14 05:32:32 +01:00
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
2022-01-13 05:24:03 +01:00
2023-03-02 07:59:14 +01:00
refreshSurface = false;
2023-03-05 07:16:44 +01:00
input_display_list = [
["Surface", false], 0, 1, 2,
["Packing", false], 3, 4, 5, 6, 7,
]
2022-01-18 05:31:19 +01:00
static step = function() {
2022-12-23 04:45:52 +01:00
var grup = inputs[| 1].getValue();
var pack = inputs[| 3].getValue();
2022-01-13 05:24:03 +01:00
2023-03-05 07:16:44 +01:00
if(pack == 0) inputs[| 5].editWidget.data = [ "Top", "Center", "Bottom" ];
else inputs[| 5].editWidget.data = [ "Left", "Center", "Right" ];
2022-12-23 04:45:52 +01:00
inputs[| 2].setVisible(grup == SPRITE_ANIM_GROUP.animation);
inputs[| 4].setVisible(pack == SPRITE_STACK.grid);
2023-03-05 07:16:44 +01:00
inputs[| 5].setVisible(pack != SPRITE_STACK.grid);
2022-12-23 04:45:52 +01:00
}
2023-02-14 05:32:32 +01:00
static update = function(frame = ANIMATOR.current_frame) {
2022-12-23 04:45:52 +01:00
var inpt = inputs[| 0].getValue();
2022-01-13 05:24:03 +01:00
var grup = inputs[| 1].getValue();
var skip = inputs[| 2].getValue();
var pack = inputs[| 3].getValue();
2022-12-23 04:45:52 +01:00
var grid = inputs[| 4].getValue();
2022-01-13 05:24:03 +01:00
var alig = inputs[| 5].getValue();
2023-03-05 07:16:44 +01:00
var spac = inputs[| 6].getValue();
var padd = inputs[| 7].getValue();
2022-01-13 05:24:03 +01:00
2023-02-14 05:32:32 +01:00
if(grup != SPRITE_ANIM_GROUP.animation) {
2023-03-02 07:59:14 +01:00
initRender();
2023-02-14 05:32:32 +01:00
return;
2023-03-02 07:59:14 +01:00
} else if(ANIMATOR.rendering & ANIMATOR.frame_progress && ANIMATOR.current_frame == 0 && !refreshSurface) {
var skip = inputs[| 2].getValue();
if(is_array(inpt) && array_length(inpt) == 0) return;
var arr = is_array(inpt);
if(!arr) inpt = [ inpt ];
var _surf = [];
2023-03-05 07:16:44 +01:00
var amo = floor(ANIMATOR.frames_total / skip);
2023-03-02 07:59:14 +01:00
for(var i = 0; i < array_length(inpt); i++) {
if(!is_surface(inpt[i])) continue;
2023-03-05 07:16:44 +01:00
var sw = surface_get_width(inpt[i]);
var sh = surface_get_height(inpt[i]);
var ww = sw, hh = sh;
2023-03-02 07:59:14 +01:00
switch(pack) {
2023-03-05 07:16:44 +01:00
case SPRITE_STACK.horizontal :
ww = sw * amo + spac * (amo - 1);
2023-03-02 07:59:14 +01:00
break;
case SPRITE_STACK.vertical :
2023-03-05 07:16:44 +01:00
hh = sh * amo + spac * (amo - 1);
2023-03-02 07:59:14 +01:00
break;
case SPRITE_STACK.grid :
var amo = floor(ANIMATOR.frames_total / skip);
var col = inputs[| 4].getValue();
var row = ceil(amo / col);
2023-03-05 07:16:44 +01:00
ww = sw * col + spac * (col - 1);
hh = sh * row + spac * (row - 1);
2023-03-02 07:59:14 +01:00
break;
}
2023-03-05 07:16:44 +01:00
ww += padd[0] + padd[2];
hh += padd[1] + padd[3];
2023-03-02 07:59:14 +01:00
_surf[i] = surface_create_valid(ww, hh);
surface_set_target(_surf[i]);
draw_clear_alpha(0, 0);
surface_reset_target();
refreshSurface = true;
}
if(!arr) _surf = array_safe_get(_surf, 0);
outputs[| 0].setValue(_surf);
2023-02-14 05:32:32 +01:00
}
2023-03-02 07:59:14 +01:00
2022-01-13 05:24:03 +01:00
if(safe_mod(ANIMATOR.current_frame, skip) != 0) return;
if(array_length(anim_drawn) != ANIMATOR.frames_total)
array_resize(anim_drawn, ANIMATOR.frames_total);
if(ANIMATOR.current_frame < ANIMATOR.frames_total) {
if(anim_drawn[ANIMATOR.current_frame]) return;
2022-12-23 04:45:52 +01:00
2022-01-13 05:24:03 +01:00
if(ANIMATOR.is_playing && ANIMATOR.frame_progress) {
if(is_array(inpt) && array_length(inpt) == 0) return;
if(!is_array(inpt)) inpt = [ inpt ];
}
}
2023-03-02 07:59:14 +01:00
var oupt = outputs[| 0].getValue();
2022-01-13 05:24:03 +01:00
if(is_array(oupt) && (array_length(inpt) != array_length(oupt))) return;
var drawn = false;
2023-03-05 07:16:44 +01:00
var px = padd[2];
var py = padd[1];
2022-01-13 05:24:03 +01:00
for(var i = 0; i < array_length(inpt); i++) {
if(!is_surface(inpt[i])) break;
2022-09-21 06:09:40 +02:00
var oo = noone;
2022-01-13 05:24:03 +01:00
if(!is_array(oupt)) oo = oupt;
else oo = oupt[i];
2023-02-14 05:32:32 +01:00
if(!is_surface(oo)) break;
2022-01-13 05:24:03 +01:00
var ww = surface_get_width(oo);
var hh = surface_get_height(oo);
var _w = surface_get_width(inpt[i]);
var _h = surface_get_height(inpt[i]);
2023-02-14 05:32:32 +01:00
var _frame = floor(ANIMATOR.current_frame / skip);
2022-01-13 05:24:03 +01:00
surface_set_target(oo);
2023-02-14 05:32:32 +01:00
BLEND_OVERRIDE;
2022-01-13 05:24:03 +01:00
switch(pack) {
case SPRITE_STACK.horizontal :
2023-03-05 07:16:44 +01:00
var px = padd[2] + _frame * _w + max(0, _frame - 1) * spac;
2022-01-13 05:24:03 +01:00
switch(alig) {
case 0 :
draw_surface_safe(inpt[i], px, py);
break;
case 1 :
draw_surface_safe(inpt[i], px, py + (hh - _h) / 2);
break;
case 2 :
draw_surface_safe(inpt[i], px, py + (hh - _h));
break;
}
break;
case SPRITE_STACK.vertical :
2023-03-05 07:16:44 +01:00
var py = padd[1] + _frame * _h + max(0, _frame - 1) * spac;
2022-01-13 05:24:03 +01:00
switch(alig) {
case 0 :
draw_surface_safe(inpt[i], px, py);
break;
case 1 :
draw_surface_safe(inpt[i], px + (ww - _w) / 2, py);
break;
case 2 :
draw_surface_safe(inpt[i], px + (ww - _w), py);
break;
}
break;
case SPRITE_STACK.grid :
var col = inputs[| 4].getValue();
2023-02-14 05:32:32 +01:00
var _row = floor(_frame / col);
var _col = safe_mod(_frame, col);
2022-01-13 05:24:03 +01:00
2023-03-05 07:16:44 +01:00
px = padd[2] + _col * _w + max(0, _col - 1) * spac;
py = padd[1] + _row * _h + max(0, _row - 1) * spac;
2022-01-13 05:24:03 +01:00
2023-03-02 07:59:14 +01:00
//print(display_name + ": " + string(ANIMATOR.current_frame) + ", " + string(inpt[i]) + "| " + string(px) + ", " + string(py));
2022-01-13 05:24:03 +01:00
draw_surface_safe(inpt[i], px, py);
break;
}
drawn = true;
2023-01-04 02:30:04 +01:00
2023-02-14 05:32:32 +01:00
BLEND_NORMAL;
2022-01-13 05:24:03 +01:00
surface_reset_target();
}
2023-02-14 05:32:32 +01:00
if(drawn)
2023-01-04 02:30:04 +01:00
anim_drawn[ANIMATOR.current_frame] = true;
2023-02-14 05:32:32 +01:00
}
2023-03-02 07:59:14 +01:00
static onInspectorUpdate = function(updateAll = true) {
2023-02-14 05:32:32 +01:00
var key = ds_map_find_first(NODE_MAP);
repeat(ds_map_size(NODE_MAP)) {
var node = NODE_MAP[? key];
key = ds_map_find_next(NODE_MAP, key);
if(!node.active) continue;
if(instanceof(node) != "Node_Render_Sprite_Sheet") continue;
node.initRender();
2023-01-04 02:30:04 +01:00
}
2022-01-13 05:24:03 +01:00
}
2023-03-02 07:59:14 +01:00
static initRender = function() {
2022-01-13 05:24:03 +01:00
for(var i = 0; i < array_length(anim_drawn); i++) anim_drawn[i] = false;
var inpt = inputs[| 0].getValue();
var grup = inputs[| 1].getValue();
var pack = inputs[| 3].getValue();
var alig = inputs[| 5].getValue();
2023-03-05 07:16:44 +01:00
var spac = inputs[| 6].getValue();
var padd = inputs[| 7].getValue();
2022-01-13 05:24:03 +01:00
if(grup == SPRITE_ANIM_GROUP.animation) {
2023-03-02 07:59:14 +01:00
refreshSurface = false;
2022-12-19 13:35:30 +01:00
if(!LOADING && !APPENDING) {
ANIMATOR.setFrame(-1);
ANIMATOR.is_playing = true;
2022-12-23 04:45:52 +01:00
ANIMATOR.rendering = true;
2023-01-04 02:30:04 +01:00
ANIMATOR.frame_progress = true;
2022-12-19 13:35:30 +01:00
}
2022-01-13 05:24:03 +01:00
} else {
if(is_array(inpt)) {
if(array_length(inpt) == 0) return;
var ww = 0;
var hh = 0;
switch(pack) {
case SPRITE_STACK.horizontal :
for(var i = 0; i < array_length(inpt); i++) {
ww += surface_get_width(inpt[i]);
2023-03-05 07:16:44 +01:00
if(i) ww += spac;
2022-01-13 05:24:03 +01:00
hh = max(hh, surface_get_height(inpt[i]));
}
break;
case SPRITE_STACK.vertical :
for(var i = 0; i < array_length(inpt); i++) {
ww = max(ww, surface_get_width(inpt[i]));
hh += surface_get_height(inpt[i]);
2023-03-05 07:16:44 +01:00
if(i) hh += spac;
2022-01-13 05:24:03 +01:00
}
break;
case SPRITE_STACK.grid :
var amo = array_length(inpt);
var col = inputs[| 4].getValue();
var row = ceil(amo / col);
var row_w = 0;
var row_h = 0;
for(var i = 0; i < row; i++) {
var row_w = 0;
var row_h = 0;
2023-03-05 07:16:44 +01:00
2022-01-13 05:24:03 +01:00
for(var j = 0; j < col; j++) {
var index = i * col + j;
if(index >= amo) break;
row_w += surface_get_width(inpt[index]);
2023-03-05 07:16:44 +01:00
if(j) row_w += spac;
2022-01-13 05:24:03 +01:00
row_h = max(row_h, surface_get_height(inpt[index]));
}
ww = max(ww, row_w);
2023-03-05 07:16:44 +01:00
hh += row_h
if(i) hh += spac;
2022-01-13 05:24:03 +01:00
}
break;
}
2023-03-05 07:16:44 +01:00
ww += padd[0] + padd[2];
hh += padd[1] + padd[3];
2022-11-03 11:44:49 +01:00
var _surf = surface_create_valid(ww, hh);
2022-01-13 05:24:03 +01:00
surface_set_target(_surf);
draw_clear_alpha(0, 0);
2023-02-14 05:32:32 +01:00
BLEND_OVERRIDE;
2022-01-13 05:24:03 +01:00
switch(pack) {
case SPRITE_STACK.horizontal :
2023-03-05 07:16:44 +01:00
var px = padd[2];
var py = padd[1];
2022-01-13 05:24:03 +01:00
for(var i = 0; i < array_length(inpt); i++) {
var _w = surface_get_width(inpt[i]);
var _h = surface_get_height(inpt[i]);
switch(alig) {
case 0 :
draw_surface_safe(inpt[i], px, py);
break;
case 1 :
draw_surface_safe(inpt[i], px, py + (hh - _h) / 2);
break;
case 2 :
draw_surface_safe(inpt[i], px, py + (hh - _h));
break;
}
2023-03-05 07:16:44 +01:00
px += _w + spac;
2022-01-13 05:24:03 +01:00
}
break;
case SPRITE_STACK.vertical :
2023-03-05 07:16:44 +01:00
var px = padd[2];
var py = padd[1];
2022-01-13 05:24:03 +01:00
for(var i = 0; i < array_length(inpt); i++) {
var _w = surface_get_width(inpt[i]);
var _h = surface_get_height(inpt[i]);
switch(alig) {
case 0 :
draw_surface_safe(inpt[i], px, py);
break;
case 1 :
draw_surface_safe(inpt[i], px + (ww - _w) / 2, py);
break;
case 2 :
draw_surface_safe(inpt[i], px + (ww - _w), py);
break;
}
2023-03-05 07:16:44 +01:00
py += _h + spac;
2022-01-13 05:24:03 +01:00
}
break;
case SPRITE_STACK.grid :
var amo = array_length(inpt);
var col = inputs[| 4].getValue();
var row = ceil(amo / col);
var row_w = 0;
var row_h = 0;
2023-03-05 07:16:44 +01:00
var px = padd[2];
var py = padd[1];
2022-01-13 05:24:03 +01:00
for(var i = 0; i < row; i++) {
var row_w = 0;
var row_h = 0;
2023-03-05 07:16:44 +01:00
px = padd[2];
2022-01-13 05:24:03 +01:00
for(var j = 0; j < col; j++) {
var index = i * col + j;
if(index >= amo) break;
var _w = surface_get_width(inpt[index]);
var _h = surface_get_height(inpt[index]);
draw_surface_safe(inpt[index], px, py);
2023-03-05 07:16:44 +01:00
px += _w + spac;
2022-01-13 05:24:03 +01:00
row_h = max(row_h, _h);
}
2023-03-05 07:16:44 +01:00
py += row_h + spac;
2022-01-13 05:24:03 +01:00
}
break;
2023-01-17 08:11:55 +01:00
}
2023-02-14 05:32:32 +01:00
BLEND_NORMAL;
2022-01-13 05:24:03 +01:00
surface_reset_target();
outputs[| 0].setValue(_surf);
2022-12-23 04:45:52 +01:00
} else
2022-01-13 05:24:03 +01:00
outputs[| 0].setValue(inpt);
}
}
}