Ouroboros/Scripts/snake_part.gd

130 lines
3.5 KiB
GDScript

extends Area2D
class_name SnakePart
const TILE_SIZE = 20
enum PartTypes {HEAD, BODY, TAIL, DEAD}
var part_type : PartTypes = PartTypes.HEAD
var current_direction : Vector2 = Vector2.RIGHT
var inputs : Dictionary[String, Vector2] = {"right": Vector2.RIGHT,
"left": Vector2.LEFT,
"up": Vector2.UP,
"down": Vector2.DOWN}
@onready
var raycast_right = $RightRayCast2D
@onready
var raycast_left = $LeftRayCast2D
@onready
var raycast_up = $UpRayCast2D
@onready
var raycast_down = $DownRayCast2D
var snake_part_obj = preload("res://Scenes/snake_part.tscn")
@onready
var timer_ref = $"../Timer"
signal do_movement(new_dir)
func _ready() -> void:
if part_type == PartTypes.HEAD:
# Add to group for easy access from other nodes
add_to_group("Head")
# Set up a body part
var body = snake_part_obj.instantiate()
body.part_type = PartTypes.BODY
body.position = (position - current_direction * TILE_SIZE).snapped(Vector2.ONE * TILE_SIZE)
get_parent().add_child.call_deferred(body)
do_movement.connect(body.process_movement)
# Set up a tail part
var tail = snake_part_obj.instantiate()
tail.part_type = PartTypes.TAIL
tail.position = (position - current_direction * TILE_SIZE * 2).snapped(Vector2.ONE * TILE_SIZE)
get_parent().add_child.call_deferred(tail)
body.do_movement.connect(tail.process_movement)
else:
raycast_down.queue_free()
raycast_up.queue_free()
raycast_left.queue_free()
raycast_right.queue_free()
#elif part_type == PartTypes.BODY:
#area_entered.connect(_on_part_area_entered)
#elif part_type == PartTypes.TAIL:
#area_entered.connect(_on_part_area_entered)
func process_movement(new_direction : Vector2) -> void:
if part_type == PartTypes.HEAD:
check_movement()
position = (position + current_direction * TILE_SIZE).snapped(Vector2.ONE * TILE_SIZE)
#process_collisions();
do_movement.emit(current_direction)
if new_direction != Vector2.ZERO:
current_direction = new_direction
func check_movement() -> void:
# Get the correct raycast for the direction we are moving
var raycast_to_use : RayCast2D
if current_direction == Vector2.RIGHT:
raycast_to_use = raycast_right
elif current_direction == Vector2.LEFT:
raycast_to_use = raycast_left
elif current_direction == Vector2.UP:
raycast_to_use = raycast_up
elif current_direction == Vector2.DOWN:
raycast_to_use = raycast_down
# Look using the raycast for anything to collide with
var object_in_path : Object = raycast_to_use.get_collider()
if object_in_path == null:
return
if object_in_path is SnakePart:
match object_in_path.part_type:
PartTypes.BODY:
lose_game()
PartTypes.TAIL:
ouroboros()
#func process_collisions() -> void:
#var colliding_areas = get_overlapping_areas()
#for area in colliding_areas:
#if area is SnakePart:
#match area.part_type:
#PartTypes.BODY:
#lose_game()
#PartTypes.TAIL:
#ouroboros()
func lose_game() -> void:
# You lose!
print("Game lost")
timer_ref.stop()
func ouroboros() -> void:
print("You have achieved the ouroboros!")
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventKey and part_type == PartTypes.HEAD:
for dir in inputs.keys():
if event.is_action_pressed(dir):
current_direction = inputs[dir]
#func _on_part_area_entered(area: Area2D) -> void:
#if area.get("part_type") != PartTypes.HEAD:
#return
#if part_type == PartTypes.BODY or part_type == PartTypes.DEAD:
#lose_game()
#elif part_type == PartTypes.TAIL:
#ouroboros()
func _on_level_area_exited(area: Area2D) -> void:
lose_game()