# Duane's Dungeon - a rogue-like game # Copyright (C) 2023 Duane Robertson # spritesheet.gd - spritesheet helper # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . extends RefCounted class_name SpriteSheet var images := {} var names := {} var tile_size := Vector2i.ONE * 16 var splitter = RegEx.new() func get_names(name_file): splitter.compile('[a-z0-9_]+') var s = FileAccess.get_file_as_string(name_file) var lines = s.split('\n') var y = 0 for line in lines: var x = 0 for mat in splitter.search_all(line): names[mat.get_string()] = Vector2i(x, y) x += 1 y += 1 func _init(file, size := Vector2i.ONE * 16, border := Vector2i.ONE): var img:Image = load(file) var name_file = 'res://' + file.replace('.png', '') + '.txt' print(name_file) var tsize := size + border * 2 tile_size = size if FileAccess.file_exists(name_file): get_names(name_file) # print(names) for y in floor(img.get_height() / tsize.x): for x in floor(img.get_width() / tsize.y): var pos = Vector2i(x, y) * tsize + border var rect := Rect2i(pos, size) images[Vector2i(x, y)] = img.get_region(rect) func image(name:String, in_color=null, in_bgcolor=null, \ rotate=false, size:=Vector2i.ZERO) -> Image: var spout := Image.new() var pos:Vector2i = names.get(name, Vector2i.ZERO) var spin:Image = images[pos] var dat:PackedByteArray var color var bgcolor if in_color != null: color = Color(in_color) if in_bgcolor != null: bgcolor = Color(in_bgcolor) if rotate: spin = images[pos].duplicate() spin.rotate_90(CLOCKWISE) if color != null or bgcolor != null: if len(dat) == 0: dat = spin.get_data() for i in range(0, len(dat), 4): if color != null and dat[i+3] == 255: dat[i+0] = color.r * 255 dat[i+1] = color.g * 255 dat[i+2] = color.b * 255 elif bgcolor != null and dat[i+3] != 255: dat[i+0] = bgcolor.r * 255 dat[i+1] = bgcolor.g * 255 dat[i+2] = bgcolor.b * 255 dat[i+3] = 255 spout = Image.create_from_data(spin.get_width(), spin.get_height(), false, spin.get_format(), dat) else: spout = spin if size: var sz:Vector2i = spout.get_size() * size spout.resize(sz.x, sz.y, Image.INTERPOLATE_NEAREST) return spout func texture(name:String, color=null, bgcolor=null, rotate:=false, \ size:=Vector2i.ZERO, crop:=false) -> ImageTexture: var img:Image = image(name, color, bgcolor, rotate, size) var cropped:Rect2i if crop: cropped = img.get_used_rect() if cropped: img = img.get_region(cropped) var tex := ImageTexture.create_from_image(img) if crop and cropped: tex.set_meta('offset', cropped.position) return tex