summaryrefslogtreecommitdiff
path: root/Scenes/Entities/Enemies/Components/Movement.gd
blob: 5470a7db00f201592935d9b794513d2166ee9e3e (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 ComponentMovement
extends Node


signal direction_changed

@export_node_path("CharacterBody2D") var entityPath: NodePath
@onready var entity: CharacterBody2D = get_node(entityPath)

@export_node_path("AnimatedSprite2D") var spritePath: NodePath
@onready var sprite: AnimatedSprite2D = get_node(spritePath)

@export var SPEED: int

const DIRECTIONS = [Vector2.UP, Vector2.RIGHT, Vector2.DOWN, Vector2.LEFT]
var CURRENT_DIRECTION = Vector2.UP
var LAST_DIRECTION = Vector2.UP
var was_colliding = false

@export var timer_time: float = 3.0
@onready var MovementTimer: Timer = Timer.new()

@export var follows: bool = false
@export_range(1, 100, 1) var follow_chance: int = 100


func _ready():
	MovementTimer.wait_time = timer_time
	MovementTimer.autostart = true
	MovementTimer.connect("timeout", Callable(_on_movement_timer_timeout))
	add_child(MovementTimer)


func physics_process(delta):
	if CURRENT_DIRECTION == Vector2.UP:
		entity.velocity.y -= SPEED
		if sprite.sprite_frames.has_animation("up"):
			sprite.play("up")
	elif CURRENT_DIRECTION == Vector2.DOWN:
		entity.velocity.y += SPEED
		if sprite.sprite_frames.has_animation("down"):
			sprite.play("down")
	elif CURRENT_DIRECTION == Vector2.LEFT:
		entity.velocity.x -= SPEED
		if sprite.sprite_frames.has_animation("left"):
			sprite.play("left")
	elif CURRENT_DIRECTION == Vector2.RIGHT:
		entity.velocity.x += SPEED
		if sprite.sprite_frames.has_animation("right"):
			sprite.play("right")
	
	if sprite.sprite_frames.has_animation("default"):
		sprite.play("default")
	
	var collision = entity.move_and_collide(entity.velocity * delta)
	entity.velocity = entity.velocity.lerp(Vector2(0, 0), 1) # speed too low => no collision
	
	if collision:
		was_colliding = true
		if MovementTimer.time_left > 0:
			_on_movement_timer_timeout()
	else:
		was_colliding = false
	
	return collision


func _on_movement_timer_timeout():
	var randomize_direction = false

	if follows and randi_range(0, 100) <= follow_chance:
		var player_direction = entity.position.direction_to(Global.player.position)
		if abs(player_direction.x) >= abs(player_direction.y):
			if player_direction.x >= 0:
				CURRENT_DIRECTION = Vector2.RIGHT
			elif player_direction.x < 0:
				CURRENT_DIRECTION = Vector2.LEFT
		elif abs(player_direction.y) > abs(player_direction.x):
			if player_direction.y >= 0:
				CURRENT_DIRECTION = Vector2.DOWN
			elif player_direction.y < 0:
				CURRENT_DIRECTION = Vector2.UP
		
		if was_colliding and LAST_DIRECTION == CURRENT_DIRECTION:
			randomize_direction = true
	else:
		randomize_direction = true
		
	if randomize_direction:
		var directions = DIRECTIONS.duplicate()
		
		directions.remove_at(directions.find(CURRENT_DIRECTION))
		directions.shuffle()
		
		CURRENT_DIRECTION = directions[0]

	emit_signal("direction_changed", CURRENT_DIRECTION)
	LAST_DIRECTION = CURRENT_DIRECTION
	
	if not sprite.sprite_frames.has_animation("default"):
		var frame = sprite.frame
		var progress = sprite.frame_progress
		if CURRENT_DIRECTION == Vector2.UP and sprite.sprite_frames.has_animation("up"):
			sprite.play("up")
		elif CURRENT_DIRECTION == Vector2.DOWN and sprite.sprite_frames.has_animation("down"):
			sprite.play("down")
		elif CURRENT_DIRECTION == Vector2.LEFT and sprite.sprite_frames.has_animation("left"):
			sprite.play("left")
		elif CURRENT_DIRECTION == Vector2.RIGHT and sprite.sprite_frames.has_animation("right"):
			sprite.play("right")
		sprite.set_frame_and_progress(frame, progress)
	
	MovementTimer.start()