godot-knot/game/logic.gd

188 lines
5.5 KiB
GDScript

extends Node
const number_of_circles = 10
var circle_node = preload("res://game/objects/circle/circle.tscn")
# Called when the node enters the scene tree for the first time.
func _ready():
hide_end_screen()
new_game()
func new_game():
generate_knot()
check_all_lines()
func generate_knot():
#clrear previous
for child in $"../canvas/circles".get_children():
child.queue_free()
for child in $"../canvas/lines".get_children():
child.queue_free()
var grid = []
var grid_size = ceil(sqrt(number_of_circles))
for i in range(number_of_circles):
var circle = circle_node.instantiate()
circle.set_global_position(Vector2(randi_range(100, 1000), randi_range(100, 500)))
#circle.get_child(3).text = str(i)
grid.append(circle)
# make connection
var neighbour_indexes = [-grid_size+1, 1, grid_size] #, grid_size+1]
for i in range(grid_size):
for j in range(grid_size-1):
var index = i*grid_size+j
for offset in neighbour_indexes:
if index+offset >= 0 and index+offset < grid.size() and index < grid.size():
#print(index, index+offset, grid.size()-1)
#print("conenct ", index, " to ", index+offset)
connect_circles(grid[index], grid[index+offset])
for circle in grid:
$"../canvas/circles".add_child(circle)
circle.raised.connect(check_all_lines)
#return grid
#func place_circles():
#for circle in $"../canvas/circles".get_children():
func connect_circles(circle1, circle2):
#check already connected
for line in circle1.attached_lines.keys():
if line in circle2.attached_lines.keys():
return false
var new_line = Line2D.new()
new_line.width = 4
new_line.add_point(circle1.position)
new_line.add_point(circle2.position)
circle1.add_line(new_line, 0)
circle2.add_line(new_line, 1)
$"../canvas/lines".add_child(new_line)
return true
func check_all_lines():
var all_lines = $"../canvas/lines".get_children()
var redlist = []
for line in all_lines:
for other_line in all_lines:
if line != other_line and not line in redlist:
var intersection = detect_intersection(line, other_line)
if intersection:
line.set_default_color(Color.CRIMSON)
other_line.set_default_color(Color.CRIMSON)
redlist.append(line)
redlist.append(other_line)
else:
line.set_default_color(Color.WHITE)
if redlist.is_empty():
show_end_screen()
func detect_intersection(line1, line2):
var line1p1 = line1.get_point_position(0)
var line1p2 = line1.get_point_position(1)
var line2p1 = line2.get_point_position(0)
var line2p2 = line2.get_point_position(1)
var p0_x = line1p1.x
var p0_y = line1p1.y
var p1_x = line1p2.x
var p1_y = line1p2.y
var p2_x = line2p1.x
var p2_y = line2p1.y
var p3_x = line2p2.x
var p3_y = line2p2.y
if line1p1 != line2p1 and line1p1 != line2p2:
if line1p2 != line2p1 and line1p2 != line2p2:
var s1_x = p1_x - p0_x
var s1_y = p1_y - p0_y
var s2_x = p3_x - p2_x
var s2_y = p3_y - p2_y
var s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y)
var t = (s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y)
if s >= 0 and s <= 1 and t >= 0 and t <= 1:
#var debug_x = p0_x + (t * s1_x)
#var debug_y = p0_y + (t * s1_y)
#print( debug_x, debug_y )
#place_debug_marker(debug_x, debug_y)
return true
return false
func show_end_screen():
$"../canvas/end_screen".show()
for child in $"../canvas/end_screen".get_children():
child.show()
func hide_end_screen():
$"../canvas/end_screen".hide()
for child in $"../canvas/end_screen".get_children():
child.hide()
func _on_button_pressed():
hide_end_screen()
new_game()
#func place_debug_marker(x, y):
#var debug_marker = debug_marker_node.instantiate()
#debug_marker.set_global_position(Vector2(x, y))
#$"../canvas/debug_markers".add_child(debug_marker)
##stolen from
##https://code.whatever.social/questions/
##563198/how-do-you-detect-where-two-line-segments-intersect#15001181
#func detect_intersection(line1, line2):
#var x1 = line1.get_point_position(0).x
#var y1 = line1.get_point_position(0).y
#var x2 = line1.get_point_position(1).x
#var y2 = line1.get_point_position(1).y
#var x3 = line2.get_point_position(0).x
#var y3 = line2.get_point_position(0).y
#var x4 = line2.get_point_position(1).x
#var y4 = line2.get_point_position(1).y
#if x1 == x2:
#var x1x2 = (x3 == x4 and x1 != x3)
#print(x1x2)
#return x1x2
#elif x3 == x4:
#return true
#else:
#var m1 = (y1-y2)/(x1-x2)
#var m2 = (y3-y4)/(x3-x4)
#return m1 != m2
##stolen from https://gist.github.com/kylemcdonald/6132fc1c29fd3767691442ba4bc84018
## intersection between line(p1, p2) and line(p3, p4)
##func intersect(p1, p2, p3, p4):
#func detect_intersection(line1, line2):
#var line1point1 = line1.get_point_position(0)
#var line1point2 = line1.get_point_position(1)
#var line2point1 = line2.get_point_position(0)
#var line2point2 = line2.get_point_position(1)
#var x1 = line1point1.x
#var y1 = line1point1.y
#var x2 = line1point2.x
#var y2 = line1point2.y
#var x3 = line2point1.x
#var y3 = line2point1.y
#var x4 = line2point2.x
#var y4 = line2point2.y
#var denom = (y4-y3)*(x2-x1) - (x4-x3)*(y2-y1)
#print("denom: ", denom)
#if denom == 0: # parallel
#return false
#var ua = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / denom
#print("ua: ", ua)
#if ua < 0 or ua > 1: # out of range
#return false
#var ub = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / denom
#print("ub: ", ub)
#if ub < 0 or ub > 1: # out of range
#return false
#var x = x1 + ua * (x2-x1)
#var y = y1 + ua * (y2-y1)
#var result = [x, y]
#print("result: ", result)
#return result