Hi thank you so much for answering. Unfortunately I canât upload it says since im a new user (which is the case). But I will try to upload it on youtube or something. Edit - Link: https://1drv.ms/v/c/2c02bfa6495518cb/EfTE3c_7wg1DhHmj9vZDPD4BHvuJRNDrq-Ga1aBDc7slpw?e=zwLpS4
The Scene Tree looks like that:
Basically its a coloring pixels clone. At first I select an image, and then i wrote an algorithm to find the top 10 colors of that image. The image then gets pixelized and each pixel gets a tile in the tilemap.
After scaling the image has 24576 pixels (so 24576 tiles in total).
Why 3 tilemap layers? One for the actual color, one for the number that is above the tile, and one for the border.
The script for the âmainâ logic (with comments):
class_name CreateFromImage
extends Node2D
@onready var pixel_colors: TileMapLayer = $PixelColors
@onready var pixel_numbers: TileMapLayer = $PixelNumbers
@onready var confirm_dialog: VBoxContainer = $CanvasLayer/ConfirmDialog
@onready var file_dialog: FileDialog = $FileDialog
@export var pixelation: int = 10
var modulated_tile_cache: Dictionary
var used_colors_cache: Dictionary
var number_counter: int = 1
var drawing
# for each unique color i create an alternate tile (base tile is 16x16 white rect)
func create_alternate_tile(color: Color):
var source = pixel_colors.tile_set.get_source(0) as TileSetAtlasSource
var alt_tile_id = source.create_alternative_tile(Vector2i.ZERO)
var tile_data = source.get_tile_data(Vector2i.ZERO, alt_tile_id)
tile_data.modulate = color
modulated_tile_cache[color] = alt_tile_id
#
func create_tiles_from_img(img: Image):
drawing = Drawing.new()
var pixels = []
var w = img.get_width()
var h = img.get_height()
for x in range(w):
var row = []
for y in range(h):
var color = img.get_pixel(x, y)
if modulated_tile_cache.has(color):
var alt_tile_id = modulated_tile_cache[color]
pixel_colors.set_cell(Vector2i(x, y), 0, Vector2i.ZERO, alt_tile_id)
else:
create_alternate_tile(color)
var alt_tile_id = modulated_tile_cache[color]
pixel_colors.set_cell(Vector2i(x, y), 0, Vector2i.ZERO, alt_tile_id)
var pixel_color = PixelColor.new()
if used_colors_cache.has(color):
var number = used_colors_cache[color]
pixel_color.initialize(color, number)
else:
used_colors_cache[color] = number_counter
var number = used_colors_cache[color]
pixel_color.initialize(color, number)
number_counter += 1
var number = used_colors_cache[color]
pixel_numbers.set_cell(Vector2i(x, y), 0, Vector2i(number - 1, 0), 1)
var pixel = Pixel.new()
pixel.initialize(Vector2i(x, y), pixel_color)
row.append(pixel)
pixels.append(row)
drawing.initialize("test", pixels)
func reset():
pixel_colors.clear()
pixel_numbers.clear()
used_colors_cache.clear()
modulated_tile_cache.clear()
number_counter = 1
func create_image(path: String):
reset()
var img = Image.load_from_file(path)
var w = img.get_width()
var h = img.get_height()
img.resize(w / pixelation, h / pixelation, Image.INTERPOLATE_NEAREST)
# kmeans to find the top 4 colors
var palette = Utils._kmeans_generate_palette(img, 4, 4)
# recolor the pixels to these 4 colors
var new_img = Utils._apply_palette_to_image(img, palette)
# create tiles from the scaled down (pixelated image)
create_tiles_from_img(new_img)
confirm_dialog.show()
func _on_file_dialog_file_selected(path: String) -> void:
create_image(path)
func _on_button_pressed() -> void:
file_dialog.popup_centered()
func store_drawing():
#var file_name = "res://MyAwesomeDrawing.tres"
#ResourceSaver.save(drawing, file_name)
Globals.cached_drawing = drawing
Globals.cached_alt_tiles = modulated_tile_cache
Globals.cached_tile_set = pixel_colors.tile_set
func _on_ok_btn_pressed() -> void:
store_drawing()
get_tree().change_scene_to_file("res://play_scene.tscn")