75 lines
2.1 KiB
GDScript
75 lines
2.1 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
|
|
|
|
func _ready() -> void:
|
|
image = Image.create_empty(32, 32, false, Image.FORMAT_RGBA8)
|
|
dtexture = $DrawTexture
|
|
bgtexture = $Background
|
|
bgimage = bgtexture.texture.get_image()
|
|
update_texture()
|
|
|
|
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()
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if event is InputEventKey and event.pressed and not event.is_echo():
|
|
if event.keycode == KEY_Z and Input.is_key_pressed(KEY_CTRL):
|
|
undo()
|
|
return
|
|
|
|
if event is InputEventMouseButton and not event.is_echo():
|
|
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()
|