105 lines
3.2 KiB
GDScript
105 lines
3.2 KiB
GDScript
extends Node2D
|
|
|
|
var positions_history : Array
|
|
var loop_stack : Array
|
|
|
|
signal started_drawing(pos:Vector2)
|
|
signal stopped_drawing
|
|
|
|
var is_drawing = false
|
|
|
|
func _ready() -> void:
|
|
init_history_stack()
|
|
loop_stack = []
|
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
|
global_position = get_viewport_rect().size / 2
|
|
|
|
func _process(delta: float) -> void:
|
|
$IconNormal.rotation_degrees = ((get_viewport_rect().size / 2) - Vector2(-10000, -10000)).normalized().dot(Vector2.from_angle(45.))
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if event is InputEventMouseButton:
|
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
|
if event is InputEventKey:
|
|
if event.keycode == KEY_ESCAPE:
|
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
|
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
|
var direction = event.relative.normalized()
|
|
# truthfully should calibrate by mouse
|
|
# need a max speed for fair gameplay
|
|
# var speed = clamp(event.relative.length(), 0.0, 128.0)
|
|
var speed = event.relative.length()
|
|
global_position += direction * speed
|
|
restrict_cursor()
|
|
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
|
|
if not is_drawing:
|
|
emit_signal("started_drawing", global_position)
|
|
is_drawing = true
|
|
push_history_stack(global_position)
|
|
Globals.CURRENT_LINE = positions_history
|
|
else:
|
|
if is_close_to_loop():
|
|
create_valid_loop()
|
|
if is_drawing:
|
|
emit_signal("stopped_drawing", positions_history)
|
|
is_drawing = false
|
|
init_history_stack()
|
|
|
|
func get_tail(max_length: int = 32) -> Array:
|
|
var tail_length = min(positions_history.size(), max_length)
|
|
var output = positions_history.slice(positions_history.size() - tail_length, positions_history.size())
|
|
return output
|
|
|
|
func is_close_to_loop () -> bool:
|
|
if positions_history.size() < 16:
|
|
return false
|
|
|
|
var to = positions_history[positions_history.size() - 1]
|
|
var from = positions_history[0]
|
|
var distance = (to - from).length()
|
|
print(distance)
|
|
|
|
if distance < Globals.SNAP_DISTANCE:
|
|
print((to - from).length())
|
|
return true
|
|
return false
|
|
|
|
func init_history_stack() -> void:
|
|
positions_history = []
|
|
|
|
func create_valid_loop() -> void:
|
|
var smoothed_loop = positions_history
|
|
var last = 0
|
|
|
|
# clean up a bit
|
|
while (smoothed_loop.pop_back() as Vector2).distance_to(smoothed_loop[0]) < Globals.SNAP_DISTANCE / 2:
|
|
smoothed_loop.pop_back()
|
|
for i in range(1,8):
|
|
if (smoothed_loop[1] as Vector2).distance_to(smoothed_loop[0]) < Globals.SNAP_DISTANCE / 2:
|
|
smoothed_loop.pop_front()
|
|
|
|
# simplify
|
|
for j in range(1):
|
|
var new_loop = []
|
|
for i in range(0, smoothed_loop.size(), 2):
|
|
new_loop.append(smoothed_loop[i])
|
|
smoothed_loop = new_loop
|
|
|
|
loop_stack.append(smoothed_loop)
|
|
|
|
func push_history_stack(value : Vector2) -> void:
|
|
if positions_history.size() < Globals.HISTORY_LENGTH:
|
|
positions_history.append(value)
|
|
# if positions_history.size() > Globals.HISTORY_LENGTH:
|
|
# positions_history.pop_front()
|
|
|
|
func restrict_cursor() -> void:
|
|
if global_position.x < 0:
|
|
global_position.x = 0
|
|
if global_position.y < 0:
|
|
global_position.y = 0
|
|
if global_position.x > get_viewport_rect().size.x:
|
|
global_position.x = get_viewport_rect().size.x
|
|
if global_position.y > get_viewport_rect().size.y:
|
|
global_position.y = get_viewport_rect().size.y
|