Files
project-hood/scripts/menus/pumpkin_carve.gd
2025-10-28 02:22:59 +01:00

92 lines
2.4 KiB
GDScript

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()