diff options
Diffstat (limited to 'Scenes/Entities/Enemies/Snake.gd')
-rw-r--r-- | Scenes/Entities/Enemies/Snake.gd | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/Scenes/Entities/Enemies/Snake.gd b/Scenes/Entities/Enemies/Snake.gd new file mode 100644 index 0000000..a87ecf0 --- /dev/null +++ b/Scenes/Entities/Enemies/Snake.gd @@ -0,0 +1,144 @@ +extends CharacterBody2D + + +@export var speed: float = 10 + +static var detected_bombs = [] +var did_detect_bomb = false +var detected_bomb: Bomb +var detected_bomb_direction = Vector2.UP +var is_full = false + +var is_animating_state = false +var animations_default = { + "up": "up", + "down": "down", + "left": "left", + "right": "right", +} +var animations_full = { + "up": "up_full", + "down": "down_full", + "left": "left_full", + "right": "right_full", +} +var current_delta + +@onready var component_collision: ComponentCollision = $Collision +@onready var component_movement: ComponentMovement = $Movement + + +func _ready(): + add_to_group("enemies") + + component_collision.init() + component_movement.SPEED = speed + + +func _physics_process(delta): + current_delta = delta + + if not did_detect_bomb and not is_full: + component_movement.SPEED = speed + + for ray: RayCast2D in $Rays.get_children(): + if ( + ray.is_colliding() and + ray.get_collider() and + ray.get_collider().is_in_group("bombs") and + not detected_bombs.has(ray.get_collider()) + ): + did_detect_bomb = true + detected_bomb = ray.get_collider() + detected_bombs.push_front(detected_bomb) + detected_bomb.tree_exited.connect(func(): + did_detect_bomb = false + detected_bombs.erase(detected_bomb) + detected_bomb = null + ) + + if ray.name == "Down": + detected_bomb_direction = Vector2.DOWN + elif ray.name == "Up": + detected_bomb_direction = Vector2.UP + elif ray.name == "Left": + detected_bomb_direction = Vector2.LEFT + elif ray.name == "Right": + detected_bomb_direction = Vector2.RIGHT + + component_movement.SPEED = speed*4 + + if $DetectionArea.get_overlapping_bodies().has(detected_bomb): + _on_detection_area_body_entered(detected_bomb) + elif did_detect_bomb: + component_movement.CURRENT_DIRECTION = detected_bomb_direction + + if not is_animating_state: + component_movement.physics_process(delta) + + +func set_animating_state(state: bool): + is_animating_state = state + if is_animating_state: + component_movement.MovementTimer.stop() + else: + component_movement.MovementTimer.start() + + +func _on_detection_area_body_entered(_body): + if did_detect_bomb and detected_bomb: + set_animating_state(true) + + add_collision_exception_with(detected_bomb) + detected_bomb.stop() + self.z_index = detected_bomb.z_index + 1 + + if detected_bomb_direction == Vector2.UP: + $AnimatedSprite2D.play("up_bite") + smooth_over("up_bite") + elif detected_bomb_direction == Vector2.DOWN: + $AnimatedSprite2D.play("down_bite") + smooth_over("down_bite") + elif detected_bomb_direction == Vector2.LEFT: + $AnimatedSprite2D.play("left_bite") + smooth_over("left_bite") + elif detected_bomb_direction == Vector2.RIGHT: + $AnimatedSprite2D.play("right_bite") + smooth_over("right_bite") + await $AnimatedSprite2D.animation_finished + + if detected_bomb: + detected_bomb.queue_free() + component_movement.set_animations(animations_full) + is_full = true + component_movement.SPEED = speed/2 + + $Timer.start() + set_animating_state(false) + +func smooth_over (animation): + create_tween().tween_property( + self, + "position", + detected_bomb.position, + $AnimatedSprite2D.sprite_frames.get_animation_speed(animation) / $AnimatedSprite2D.sprite_frames.get_frame_count(animation) + ) + + +func _on_timer_timeout(): + set_animating_state(true) + + if component_movement.CURRENT_DIRECTION == Vector2.UP: + $AnimatedSprite2D.play("up_shrink") + elif component_movement.CURRENT_DIRECTION == Vector2.DOWN: + $AnimatedSprite2D.play("down_shrink") + elif component_movement.CURRENT_DIRECTION == Vector2.LEFT: + $AnimatedSprite2D.play("left_shrink") + elif component_movement.CURRENT_DIRECTION == Vector2.RIGHT: + $AnimatedSprite2D.play("right_shrink") + await $AnimatedSprite2D.animation_finished + + component_movement.set_animations(animations_default) + is_full = false + component_movement.SPEED = speed + set_animating_state(false) |