summaryrefslogtreecommitdiff
path: root/src/entities/actors/snake
diff options
context:
space:
mode:
Diffstat (limited to 'src/entities/actors/snake')
-rw-r--r--src/entities/actors/snake/scenes/Body.tscn13
-rw-r--r--src/entities/actors/snake/scenes/Head.tscn12
-rw-r--r--src/entities/actors/snake/scenes/Tail.tscn12
-rw-r--r--src/entities/actors/snake/scripts/generic_segment.gd5
-rw-r--r--src/entities/actors/snake/scripts/head.gd32
-rw-r--r--src/entities/actors/snake/scripts/snake.gd87
6 files changed, 124 insertions, 37 deletions
diff --git a/src/entities/actors/snake/scenes/Body.tscn b/src/entities/actors/snake/scenes/Body.tscn
index 93020b2..8e4a8a4 100644
--- a/src/entities/actors/snake/scenes/Body.tscn
+++ b/src/entities/actors/snake/scenes/Body.tscn
@@ -1,14 +1,23 @@
-[gd_scene load_steps=3 format=2]
+[gd_scene load_steps=4 format=2]
[ext_resource path="res://entities/actors/snake/sprites/body.png" type="Texture" id=1]
[ext_resource path="res://entities/actors/snake/scripts/generic_segment.gd" type="Script" id=2]
+[sub_resource type="CapsuleShape2D" id=1]
+radius = 5.99999
+height = 4.00002
+
[node name="BodyPathFollow" type="PathFollow2D"]
loop = false
script = ExtResource( 2 )
-[node name="Body" type="Node2D" parent="."]
+[node name="Body" type="Area2D" parent="."]
rotation = 1.5708
+collision_layer = 2
+collision_mask = 0
[node name="Sprite" type="Sprite" parent="Body"]
texture = ExtResource( 1 )
+
+[node name="Collision" type="CollisionShape2D" parent="Body"]
+shape = SubResource( 1 )
diff --git a/src/entities/actors/snake/scenes/Head.tscn b/src/entities/actors/snake/scenes/Head.tscn
index 2dc1666..22aa7e6 100644
--- a/src/entities/actors/snake/scenes/Head.tscn
+++ b/src/entities/actors/snake/scenes/Head.tscn
@@ -1,10 +1,18 @@
-[gd_scene load_steps=3 format=2]
+[gd_scene load_steps=4 format=2]
[ext_resource path="res://entities/actors/snake/sprites/head.png" type="Texture" id=1]
[ext_resource path="res://entities/actors/snake/scripts/head.gd" type="Script" id=2]
-[node name="HeadPoint" type="Node2D"]
+[sub_resource type="CircleShape2D" id=1]
+radius = 5.0
+
+[node name="Head" type="KinematicBody2D"]
+position = Vector2( -1, 0 )
+collision_mask = 0
script = ExtResource( 2 )
[node name="Sprite" type="Sprite" parent="."]
texture = ExtResource( 1 )
+
+[node name="Collision" type="CollisionShape2D" parent="."]
+shape = SubResource( 1 )
diff --git a/src/entities/actors/snake/scenes/Tail.tscn b/src/entities/actors/snake/scenes/Tail.tscn
index bb30c42..17e8ec5 100644
--- a/src/entities/actors/snake/scenes/Tail.tscn
+++ b/src/entities/actors/snake/scenes/Tail.tscn
@@ -1,15 +1,23 @@
-[gd_scene load_steps=3 format=2]
+[gd_scene load_steps=4 format=2]
[ext_resource path="res://entities/actors/snake/sprites/tail.png" type="Texture" id=1]
[ext_resource path="res://entities/actors/snake/scripts/generic_segment.gd" type="Script" id=2]
+[sub_resource type="CircleShape2D" id=1]
+radius = 4.12311
+
[node name="TailPathFollow" type="PathFollow2D"]
loop = false
script = ExtResource( 2 )
TYPE = "tail"
-[node name="Tail" type="Node2D" parent="."]
+[node name="Tail" type="Area2D" parent="."]
rotation = 1.5708
+collision_layer = 4
+collision_mask = 0
[node name="Sprite" type="Sprite" parent="Tail"]
texture = ExtResource( 1 )
+
+[node name="Collision" type="CollisionShape2D" parent="Tail"]
+shape = SubResource( 1 )
diff --git a/src/entities/actors/snake/scripts/generic_segment.gd b/src/entities/actors/snake/scripts/generic_segment.gd
index ec34f43..6c65d11 100644
--- a/src/entities/actors/snake/scripts/generic_segment.gd
+++ b/src/entities/actors/snake/scripts/generic_segment.gd
@@ -1,8 +1,7 @@
extends PathFollow2D
export(String, "body", "tail") var TYPE: String = "body"
-var speed: float = Global.SNAKE_SPEED
-func _process(delta: float) -> void:
- offset += speed * delta \ No newline at end of file
+func _physics_process(delta: float) -> void:
+ offset += Global.SNAKE_SPEED * delta
diff --git a/src/entities/actors/snake/scripts/head.gd b/src/entities/actors/snake/scripts/head.gd
index ea28f74..448802e 100644
--- a/src/entities/actors/snake/scripts/head.gd
+++ b/src/entities/actors/snake/scripts/head.gd
@@ -1,30 +1,36 @@
-extends Node2D
+extends KinematicBody2D
-var speed: float = Global.SNAKE_SPEED
-var rot_speed: float = Global.SNAKE_ROT_SPEED
-var position_update_interval: float = Global.SNAKE_POSITION_UPDATE_INTERVAL
+enum {
+ LEFT=-1,
+ RIGHT=1
+}
+var velocity: Vector2 = Vector2.ZERO
var _direction: Vector2 = Vector2.UP
var _time_elapsed: float = 0.0
-func _process(delta: float) -> void:
+func _physics_process(delta: float) -> void:
if Input.is_action_pressed("move_left"):
- # _direction = _direction.rotated(deg2rad(-ROT_SPEED))
- rotate(deg2rad(-rot_speed * delta))
+ _rotate_to(LEFT)
if Input.is_action_pressed("move_right"):
- # _direction = _direction.rotated(deg2rad(ROT_SPEED))
- rotate(deg2rad(rot_speed * delta))
+ _rotate_to(RIGHT)
- move_local_x(_direction.x * speed * delta)
- move_local_y(_direction.y * speed * delta)
+ velocity = _direction * Global.SNAKE_SPEED
+ # not sure if needed, worked wonders when using a Node2D instead of KB2D
+ velocity = move_and_slide(velocity)
_handle_time_elapsed(delta)
+func _rotate_to(direction: int) -> void:
+ rotate(deg2rad(direction * Global.SNAKE_ROT_SPEED * get_physics_process_delta_time()))
+ _direction = _direction.rotated(deg2rad(direction * Global.SNAKE_ROT_SPEED * get_physics_process_delta_time()))
+
+
# using a timer is not recommended for < 0.01
func _handle_time_elapsed(delta: float) -> void:
- if _time_elapsed >= position_update_interval:
- Event.emit_signal("new_curve_point", global_position)
+ if _time_elapsed >= Global.SNAKE_POSITION_UPDATE_INTERVAL:
+ Event.emit_signal("snake_path_new_point", global_position)
_time_elapsed = 0.0
_time_elapsed += delta
diff --git a/src/entities/actors/snake/scripts/snake.gd b/src/entities/actors/snake/scripts/snake.gd
index e604011..76b8bee 100644
--- a/src/entities/actors/snake/scripts/snake.gd
+++ b/src/entities/actors/snake/scripts/snake.gd
@@ -7,12 +7,30 @@ export(PackedScene) var TAIL_SEGMENT_NP: PackedScene
onready var path: Path2D = $Path
var current_body_segments: int = 0
-var max_body_segments: int = 1
-var body_segment_size: float = 16.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
func _ready():
- Event.connect("new_curve_point", self, "_on_Head_new_curve_point")
+ set_physics_process(false)
+ set_process_input(false)
+ Event.connect("snake_path_new_point", self, "_on_Head_snake_path_new_point")
+ Event.connect("snake_added_new_segment", self, "_on_Snake_snake_added_new_segment")
+ Event.connect("snake_added_initial_segments", self, "_on_Snake_snake_added_initial_segments")
+
+
+func _physics_process(delta: float) -> void:
+ if body_segment_queue.size() != 0:
+ _add_new_segment()
+
+
+func _input(event: InputEvent) -> void:
+ if event.is_action_pressed("add_body_part"):
+ _add_segment_to_queue()
func _draw() -> void:
@@ -20,23 +38,62 @@ func _draw() -> void:
draw_polyline(path.curve.get_baked_points(), Color.aquamarine, 1, true)
-func add_point_to_curve(coordinates: Vector2) -> void:
- path.curve.add_point(coordinates)
- # update call is to draw curve as there are new points
- update()
+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_add_new_segment", "body")
+ var _new_body_offset: float = body_segment_stack.back().offset - Global.SNAKE_SEGMENT_SIZE
- if current_body_segments < max_body_segments:
- add_snake_segment(BODY_SEGMENT_NP)
- elif current_body_segments == max_body_segments:
- add_snake_segment(TAIL_SEGMENT_NP)
+ _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_snake_segment(type: PackedScene) -> void:
- if path.curve.get_baked_length() >= (current_body_segments + 1.0) * body_segment_size:
+
+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_add_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_Head_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_snake_added_new_segment(type: String) -> void:
+ if type == "tail":
+ Event.emit_signal("snake_added_initial_segments")
-func _on_Head_new_curve_point(coordinates: Vector2) -> void:
- add_point_to_curve(coordinates)
+func _on_Snake_snake_added_initial_segments() -> void:
+ set_physics_process(true)
+ set_process_input(true)