extends Control var image: Image var dtexture: TextureRect var bgtexture: TextureRect var drawing: bool = false var erasing: bool = false var undo_stack: Array[Image] = [] var bgimage: Image var save_path: String = "user://pumpkin_carving.png" func _ready() -> void: dtexture = $DrawTexture bgtexture = $Background bgimage = bgtexture.texture.get_image() load_image() update_texture() func load_image() -> void: if FileAccess.file_exists(save_path): var loaded: Image = Image.load_from_file(save_path) if loaded: image = loaded return image = Image.create_empty(32, 32, false, Image.FORMAT_RGBA8) func update_texture() -> void: var texture: ImageTexture = ImageTexture.create_from_image(image) dtexture.texture = texture func push_undo_state() -> void: var copy: Image = image.duplicate() undo_stack.append(copy) if undo_stack.size() > 20: undo_stack.pop_front() func pixel(pposition: Vector2i, color: Color) -> void: if pposition.x >= 0 and pposition.x < image.get_width() and pposition.y >= 0 and pposition.y < image.get_height(): var bgcol: Color = bgimage.get_pixel(pposition.x, pposition.y) if bgcol.a > 0.01: image.set_pixel(pposition.x, pposition.y, color) func draw_at_mouse() -> void: var lpos: Vector2 = dtexture.get_local_mouse_position() var tex_size: Vector2 = Vector2(image.get_width(), image.get_height()) var dscale: Vector2 = dtexture.get_size() / tex_size var pixel_pos: Vector2i = (lpos / dscale).floor() var color: Color = Color.BLACK if not erasing else Color(0, 0, 0, 0) pixel(pixel_pos, color) update_texture() save_image() func _input(event: InputEvent) -> void: if event is InputEventMouseButton and !event.is_echo(): var mouse_pos = get_global_mouse_position() var drect = dtexture.get_global_rect() if not drect.has_point(mouse_pos): return if event.button_index == MOUSE_BUTTON_LEFT: if event.pressed: push_undo_state() drawing = true erasing = false draw_at_mouse() else: drawing = false elif event.button_index == MOUSE_BUTTON_RIGHT: if event.pressed: push_undo_state() erasing = true drawing = true draw_at_mouse() else: erasing = false drawing = false elif event is InputEventMouseMotion and drawing: draw_at_mouse() func undo() -> void: if undo_stack.size() > 0: image = undo_stack.pop_back() update_texture() save_image() func save_image() -> void: image.save_png(save_path) func _on_undo_button_pressed() -> void: undo()