summaryrefslogtreecommitdiff
path: root/Scenes/Entities/Enemies/Components/Movement.gd
diff options
context:
space:
mode:
Diffstat (limited to 'Scenes/Entities/Enemies/Components/Movement.gd')
-rw-r--r--Scenes/Entities/Enemies/Components/Movement.gd281
1 files changed, 198 insertions, 83 deletions
diff --git a/Scenes/Entities/Enemies/Components/Movement.gd b/Scenes/Entities/Enemies/Components/Movement.gd
index 3174508..98fb43a 100644
--- a/Scenes/Entities/Enemies/Components/Movement.gd
+++ b/Scenes/Entities/Enemies/Components/Movement.gd
@@ -10,11 +10,14 @@ signal direction_changed
@export_node_path("AnimatedSprite2D") var spritePath: NodePath
@onready var sprite: AnimatedSprite2D = get_node(spritePath)
-@export var SPEED: float
+@export_node_path("ComponentCollision") var component_collision_path: NodePath
+var component_collision: ComponentCollision
+
+@export_range(0, 2, 0.01) var SPEED: float
const DIRECTIONS = [Vector2.UP, Vector2.RIGHT, Vector2.DOWN, Vector2.LEFT]
var CURRENT_DIRECTION = Vector2.UP
-var LAST_DIRECTION = Vector2.UP
+var FIXED_DIRECTION = null
var was_colliding = false
var animations: Dictionary = {
@@ -24,6 +27,11 @@ var animations: Dictionary = {
"left": "left",
"right": "right",
}
+var CURRENT_ANIMATION = {
+ "name": "default",
+ "frame": 0,
+ "progress": 0,
+}
@export var timer_time: float = 3.0
@onready var MovementTimer: Timer = Timer.new()
@@ -31,101 +39,183 @@ var animations: Dictionary = {
@export var follows: bool = false
@export_range(1, 100, 1) var follow_chance: int = 100
+var is_paused = false
-func _ready():
- MovementTimer.wait_time = timer_time
- MovementTimer.autostart = true
- MovementTimer.connect("timeout", Callable(_on_movement_timer_timeout))
- add_child(MovementTimer)
+var tween: Tween
-func physics_process(delta):
- if CURRENT_DIRECTION == Vector2.UP:
- entity.velocity.y -= SPEED/2
- if sprite.sprite_frames.has_animation(animations["up"]):
- sprite.play(animations["up"])
- elif CURRENT_DIRECTION == Vector2.DOWN:
- entity.velocity.y += SPEED/2
- if sprite.sprite_frames.has_animation(animations["down"]):
- sprite.play(animations["down"])
- elif CURRENT_DIRECTION == Vector2.LEFT:
- entity.velocity.x -= SPEED/2
- if sprite.sprite_frames.has_animation(animations["left"]):
- sprite.play(animations["left"])
- elif CURRENT_DIRECTION == Vector2.RIGHT:
- entity.velocity.x += SPEED/2
- if sprite.sprite_frames.has_animation(animations["right"]):
- sprite.play(animations["right"])
-
- if sprite.sprite_frames.has_animation(animations["default"]):
- sprite.play(animations["default"])
-
- var collision = entity.move_and_collide(entity.velocity * delta)
- entity.velocity = entity.velocity.lerp(Vector2(0, 0), 1) # speed too low => no collision
-
- # todo movement along grid (maybe move position to current tile center)
- var target_grid_position = Utilities.from_grid_to_position(Utilities.get_level_position(entity) + CURRENT_DIRECTION)
- entity.position = entity.position.move_toward(target_grid_position, delta*SPEED/2)
- # todo or set velocity to tiles per SPEED per second somehow, instead of Timer
-
- if collision:
- was_colliding = true
- if MovementTimer.time_left > 0:
- _on_movement_timer_timeout()
- else:
- was_colliding = false
+func _ready():
+ #MovementTimer.wait_time = timer_time
+ #MovementTimer.autostart = true
+ #MovementTimer.connect("timeout", Callable(_on_movement_timer_timeout))
+ #add_child(MovementTimer)
+ pass
+
+func init():
+ #if component_collision_path:
+ #component_collision = get_node(component_collision_path)
+ #component_collision.collision_area.connect("collided", func(body):
+ #if check_direction_has_intersection(CURRENT_DIRECTION):
+ #tween.stop()
+ #move()
+ #)
+ ## TODO: area mit direction change detection? on solid and bomb?
- return collision
+ await get_tree().create_timer(0.2).timeout # wait for surrounding collision objects to load
+ move()
+
+
+#func physics_process(delta):
+ #if is_paused:
+ #return null
+ #
+ #if CURRENT_DIRECTION == Vector2.UP:
+ #entity.velocity.y -= SPEED/2
+ #if sprite.sprite_frames.has_animation(animations["up"]):
+ #sprite.play(animations["up"])
+ #elif CURRENT_DIRECTION == Vector2.DOWN:
+ #entity.velocity.y += SPEED/2
+ #if sprite.sprite_frames.has_animation(animations["down"]):
+ #sprite.play(animations["down"])
+ #elif CURRENT_DIRECTION == Vector2.LEFT:
+ #entity.velocity.x -= SPEED/2
+ #if sprite.sprite_frames.has_animation(animations["left"]):
+ #sprite.play(animations["left"])
+ #elif CURRENT_DIRECTION == Vector2.RIGHT:
+ #entity.velocity.x += SPEED/2
+ #if sprite.sprite_frames.has_animation(animations["right"]):
+ #sprite.play(animations["right"])
+ #
+ #if sprite.sprite_frames.has_animation(animations["default"]):
+ #sprite.play(animations["default"])
+ #
+ #var collision = entity.move_and_collide(entity.velocity * delta)
+ #entity.velocity = entity.velocity.lerp(Vector2(0, 0), 1) # speed too low => no collision
+ #
+ ## todo movement along grid (maybe move position to current tile center)
+ #var target_grid_position = Utilities.from_grid_to_position(Utilities.get_level_position(entity) + CURRENT_DIRECTION)
+ #entity.position = entity.position.move_toward(target_grid_position, delta*SPEED/2)
+ ## todo or set velocity to tiles per SPEED per second somehow, instead of Timer
+ ## use raycast in every direction to check next valid tile, move there
+ ## get start, current and end position, check if reached instead of velocity to tiles per second or Timer
+ #
+ #if collision:
+ #was_colliding = true
+ #if MovementTimer.time_left > 0:
+ #_on_movement_timer_timeout()
+ #else:
+ #was_colliding = false
+ #
+ #return collision
func set_animations(new_animations: Dictionary):
animations.merge(new_animations, true)
-func _on_movement_timer_timeout():
- var randomize_direction = false
+#func _on_movement_timer_timeout():
+ #var randomize_direction = false
+#
+ #if false and follows and randi_range(0, 100) <= follow_chance:
+ #var player_direction = entity.position.direction_to(Global.player.position)
+ #var query = PhysicsRayQueryParameters2D.new()
+ #query.set_from(entity.position)
+ #query.set_to(Global.player.position)
+ #query.set_collision_mask(entity.collision_mask)
+ #var intersection = entity.get_world_2d().direct_space_state.intersect_ray(query)
+ #if intersection:
+ #randomize_direction = true
+ #
+ #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.erase(CURRENT_DIRECTION)
+ #directions.shuffle()
+ #
+ #if not directions.is_empty():
+ #CURRENT_DIRECTION = directions[0]
+#
+ #emit_signal("direction_changed", CURRENT_DIRECTION)
+ #LAST_DIRECTION = CURRENT_DIRECTION
+ #
+ #if not sprite.sprite_frames.has_animation(animations["default"]):
+ #var frame = sprite.frame
+ #var progress = sprite.frame_progress
+ #if CURRENT_DIRECTION == Vector2.UP and sprite.sprite_frames.has_animation(animations["up"]):
+ #sprite.play(animations["up"])
+ #elif CURRENT_DIRECTION == Vector2.DOWN and sprite.sprite_frames.has_animation(animations["down"]):
+ #sprite.play(animations["down"])
+ #elif CURRENT_DIRECTION == Vector2.LEFT and sprite.sprite_frames.has_animation(animations["left"]):
+ #sprite.play(animations["left"])
+ #elif CURRENT_DIRECTION == Vector2.RIGHT and sprite.sprite_frames.has_animation(animations["right"]):
+ #sprite.play(animations["right"])
+ #sprite.set_frame_and_progress(frame, progress)
+ #
+ #MovementTimer.start()
+
+
+func pause():
+ is_paused = true
+ #MovementTimer.paused = true
+
+ process_mode = Node.PROCESS_MODE_DISABLED
- if false and follows and randi_range(0, 100) <= follow_chance:
- var player_direction = entity.position.direction_to(Global.player.position)
- var query = PhysicsRayQueryParameters2D.new()
- query.set_from(entity.position)
- query.set_to(Global.player.position)
- query.set_collision_mask(entity.collision_mask)
- var intersection = entity.get_world_2d().direct_space_state.intersect_ray(query)
- if intersection:
- randomize_direction = true
-
- 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:
+func unpause():
+ is_paused = false
+ #MovementTimer.paused = false
+
+ process_mode = Node.PROCESS_MODE_INHERIT
+ sprite.play(CURRENT_ANIMATION.name)
+ sprite.set_frame_and_progress(CURRENT_ANIMATION.frame, CURRENT_ANIMATION.progress)
+
+
+func move():
+ var can_move = true
+ var randomize_direction = false
+
+ #randomize_direction = randi() % 10 > 8
+ if check_direction_has_intersection(CURRENT_DIRECTION):
randomize_direction = true
-
+
+ var directions = DIRECTIONS.duplicate()
if randomize_direction:
- var directions = DIRECTIONS.duplicate()
-
directions.erase(CURRENT_DIRECTION)
- directions.shuffle()
-
- if not directions.is_empty():
- CURRENT_DIRECTION = directions[0]
-
+ directions.shuffle()
+
+ for idx in range(directions.size()):
+ if not check_direction_has_intersection(directions[idx]):
+ CURRENT_DIRECTION = directions[idx]
+ break
+ if idx == directions.size() - 1:
+ can_move = false
+
+ if FIXED_DIRECTION:
+ CURRENT_DIRECTION = FIXED_DIRECTION
+
emit_signal("direction_changed", CURRENT_DIRECTION)
- LAST_DIRECTION = CURRENT_DIRECTION
- if not sprite.sprite_frames.has_animation(animations["default"]):
- var frame = sprite.frame
- var progress = sprite.frame_progress
+ var frame = sprite.frame
+ var progress = sprite.frame_progress
+ var animation = sprite.animation
+ if sprite.sprite_frames.has_animation(animations["default"]):
+ sprite.play(animations["default"])
+ else:
if CURRENT_DIRECTION == Vector2.UP and sprite.sprite_frames.has_animation(animations["up"]):
sprite.play(animations["up"])
elif CURRENT_DIRECTION == Vector2.DOWN and sprite.sprite_frames.has_animation(animations["down"]):
@@ -134,6 +224,31 @@ func _on_movement_timer_timeout():
sprite.play(animations["left"])
elif CURRENT_DIRECTION == Vector2.RIGHT and sprite.sprite_frames.has_animation(animations["right"]):
sprite.play(animations["right"])
- sprite.set_frame_and_progress(frame, progress)
+ sprite.set_frame_and_progress(frame, progress)
+
+ CURRENT_ANIMATION.name = animation
+ CURRENT_ANIMATION.frame = frame
+ CURRENT_ANIMATION.progress = progress
+
+ var target_grid_position = Utilities.from_grid_to_position(Utilities.get_level_position(entity) + CURRENT_DIRECTION)
+
+ tween = create_tween()
+ if can_move:
+ tween.tween_property(entity, "position", target_grid_position, 1/SPEED).set_ease(Tween.EASE_IN_OUT)
+ else:
+ tween.tween_callback(func():
+ await get_tree().create_timer(1/SPEED).timeout
+ )
+ tween.tween_callback(func():
+ move()
+ )
+
+
+func check_direction_has_intersection(direction: Vector2):
+ var query = PhysicsRayQueryParameters2D.new()
+ query.set_from(entity.position)
+ query.set_to(Utilities.from_grid_to_position(Utilities.get_level_position(entity) + direction))
+ query.set_collision_mask(entity.collision_mask)
+ var intersection = entity.get_world_2d().direct_space_state.intersect_ray(query)
- MovementTimer.start()
+ return intersection