summaryrefslogtreecommitdiff
path: root/src/entities/actors/snake/scripts/snake.gd
blob: 01e09da2874b24188408e4df04e6e7ea51e2cdeb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
class_name Snake
extends Node2D

export(PackedScene) var BODY_SEGMENT_NP: PackedScene
export(PackedScene) var TAIL_SEGMENT_NP: PackedScene

onready var path: Path2D = $Path

var current_body_segments: int = 0
var max_body_initial_segments: int = 1
var body_segment_stack: Array
var tail_segment: PathFollow2D
# didn't konw how to name this, basically holds the current path lenght
# 	whenever the add body segment, and we use this stack to add body parts
var body_segment_queue: Array
# var distance_to_first_segment: float


func _ready():
	set_physics_process(false)
	set_process_input(false)
	Event.connect("snake_path_new_point", self, "_on_snake_path_new_point")
	Event.connect("snake_added_new_segment", self, "_on_snake_added_new_segment")
	Event.connect("snake_added_initial_segments", self, "_on_snake_added_initial_segments")

	Event.connect("food_eaten", self, "_on_food_eaten")
	# need to always set a new curve when ready, so when restarting it's af resh curve
	path.curve = Curve2D.new()


func _physics_process(delta: float) -> void:
	if body_segment_queue.size() != 0 and current_body_segments > max_body_initial_segments:
		_add_new_segment()

	# if body_segment_stack.size() > 0:
	# 	distance_to_first_segment = path.curve.get_baked_length() - body_segment_stack.front().offset
	# 	if distance_to_first_segment >= Global.SNAKE_SEGMENT_SIZE:
	# 		print(distance_to_first_segment)


func _input(event: InputEvent) -> void:
	if event.is_action_pressed("add_body_part"):
		_add_segment_to_queue()


# func _draw() -> void:
# 	if path.curve.get_baked_points().size() >= 2:
# 		draw_polyline(path.curve.get_baked_points(), Color.aquamarine, 1, true)


func _add_new_segment() -> void:
	var _path_length_threshold: float = body_segment_queue[0] + Global.SNAKE_SEGMENT_SIZE
	if path.curve.get_baked_length() >= _path_length_threshold:
		var _temp_body_segment: PathFollow2D = BODY_SEGMENT_NP.instance()
		Event.emit_signal("snake_adding_new_segment", "body")
		var _new_body_offset: float = body_segment_stack.back().offset - Global.SNAKE_SEGMENT_SIZE

		_temp_body_segment.offset = _new_body_offset
		body_segment_stack.append(_temp_body_segment)
		path.add_child(_temp_body_segment)
		tail_segment.offset = body_segment_stack.back().offset - Global.SNAKE_SEGMENT_SIZE

		body_segment_queue.pop_front()
		current_body_segments += 1
		Event.emit_signal("snake_added_new_segment", "body")


func _add_initial_segment(type: PackedScene) -> void:
	if path.curve.get_baked_length() >= (current_body_segments + 1.0) * Global.SNAKE_SEGMENT_SIZE:
		var _temp_body_segment: PathFollow2D = type.instance()
		Event.emit_signal("snake_adding_new_segment", _temp_body_segment.TYPE)
		if _temp_body_segment.TYPE == "body":
			body_segment_stack.append(_temp_body_segment)
		else:
			tail_segment = _temp_body_segment
		path.add_child(_temp_body_segment)

		current_body_segments += 1
		Event.emit_signal("snake_added_new_segment", _temp_body_segment.TYPE)


func _add_segment_to_queue() -> void:
	# need to have the queues in a fixed separation, else if the eating functionality
	#	gets spammed, all next bodyparts will be spawned almost at the same spot
	if body_segment_queue.size() == 0:
		body_segment_queue.append(path.curve.get_baked_length())
	else:
		body_segment_queue.append(body_segment_queue.back() + Global.SNAKE_SEGMENT_SIZE)


func _on_snake_path_new_point(coordinates: Vector2) -> void:
	path.curve.add_point(coordinates)
	# update call is to draw curve as there are new points to the path's curve
	# update()

	if current_body_segments < max_body_initial_segments:
		_add_initial_segment(BODY_SEGMENT_NP)
	elif current_body_segments == max_body_initial_segments:
		_add_initial_segment(TAIL_SEGMENT_NP)


func _on_snake_added_new_segment(type: String) -> void:
	if type == "tail":
		Event.emit_signal("snake_added_initial_segments")


func _on_snake_added_initial_segments() -> void:
	set_physics_process(true)
	set_process_input(true)


func _on_food_eaten(type: int, location: Vector2) -> void:
	_add_segment_to_queue()