Add fade away component, simple AI and shooting
This commit is contained in:
32
scripts/components/bullet.gd
Normal file
32
scripts/components/bullet.gd
Normal file
@@ -0,0 +1,32 @@
|
||||
class_name BulletComponent
|
||||
extends Node
|
||||
|
||||
|
||||
@export var root: Node2D
|
||||
@export var direction: Vector2 = Vector2.RIGHT
|
||||
@export var speed: float = 10.0
|
||||
@export var area2d: Area2D
|
||||
@export var visibility_notifier: VisibleOnScreenNotifier2D
|
||||
@export var life_time: float = 5.0
|
||||
@export var timer: Timer
|
||||
|
||||
func _ready() -> void:
|
||||
root = get_parent()
|
||||
visibility_notifier.screen_exited.connect(_on_screen_exited)
|
||||
area2d.body_entered.connect(on_area2d_body_entered)
|
||||
|
||||
timer.wait_time = life_time
|
||||
timer.timeout.connect(on_timer_timeout)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
root.position += direction * speed * delta
|
||||
|
||||
func _on_screen_exited() -> void:
|
||||
root.queue_free()
|
||||
|
||||
func on_area2d_body_entered(_body: Node2D) -> void:
|
||||
root.queue_free()
|
||||
|
||||
|
||||
func on_timer_timeout() -> void:
|
||||
root.queue_free()
|
@@ -2,6 +2,7 @@ class_name CollectableComponent
|
||||
extends Node
|
||||
|
||||
var root: Node
|
||||
var has_fade_away: bool = false
|
||||
|
||||
@export var area2d: Area2D
|
||||
@export var collectable_data: Resource
|
||||
@@ -16,7 +17,11 @@ func _ready() -> void:
|
||||
|
||||
root = get_parent()
|
||||
|
||||
if root.has_node("FadeAwayComponent"):
|
||||
has_fade_away = true
|
||||
|
||||
func _on_area2d_body_entered(body: Node2D) -> void:
|
||||
if body.has_node("CanPickUpComponent"):
|
||||
collected.emit(collectable_data.amount)
|
||||
root.queue_free()
|
||||
if not has_fade_away:
|
||||
root.queue_free()
|
||||
|
27
scripts/components/fade_away.gd
Normal file
27
scripts/components/fade_away.gd
Normal file
@@ -0,0 +1,27 @@
|
||||
class_name FadeAwayComponent
|
||||
extends Node
|
||||
|
||||
@export var sprite2d: Sprite2D
|
||||
@export var fade_duration: float = 1.0
|
||||
@export var speed: float = 10.0
|
||||
@export var direction: Vector2 = Vector2.UP
|
||||
@export var root: Node2D
|
||||
@export var area2d: Area2D
|
||||
|
||||
|
||||
func _ready():
|
||||
root = get_parent()
|
||||
if area2d:
|
||||
area2d.body_entered.connect(on_area2d_body_entered)
|
||||
|
||||
|
||||
func fade_away() -> void:
|
||||
var fade_tween := create_tween().set_parallel(true)
|
||||
fade_tween.tween_property(sprite2d, "modulate:a", 0, fade_duration)
|
||||
fade_tween.tween_property(sprite2d, "position", sprite2d.position + (direction * speed), fade_duration)
|
||||
await (fade_tween.finished)
|
||||
root.queue_free()
|
||||
|
||||
|
||||
func on_area2d_body_entered(_body: Node2D) -> void:
|
||||
fade_away()
|
44
scripts/components/periodic_shooting.gd
Normal file
44
scripts/components/periodic_shooting.gd
Normal file
@@ -0,0 +1,44 @@
|
||||
class_name PeriodicShootingComponent
|
||||
extends Node
|
||||
|
||||
@export var bullet_scene: PackedScene = preload("res://objects/bullet.tscn")
|
||||
@export var shoot_interval: float = 1.0
|
||||
@export var shoot_direction: Vector2 = Vector2.RIGHT
|
||||
@export var side_to_side_movement: SideToSideMovement
|
||||
@export var root: Node2D
|
||||
|
||||
var timer: Timer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
root = get_parent()
|
||||
setup_timer()
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if side_to_side_movement:
|
||||
shoot_direction = side_to_side_movement.direction if side_to_side_movement.direction != Vector2.ZERO else Vector2.RIGHT
|
||||
|
||||
func shoot() -> void:
|
||||
if shoot_direction == Vector2.ZERO:
|
||||
return
|
||||
|
||||
var bullet_instance: Node2D = bullet_scene.instantiate()
|
||||
var bullet_component: BulletComponent = bullet_instance.get_node("BulletComponent")
|
||||
bullet_instance.position = root.position
|
||||
bullet_component.direction = shoot_direction
|
||||
get_tree().current_scene.add_child(bullet_instance)
|
||||
|
||||
|
||||
func on_timer_timeout() -> void:
|
||||
shoot()
|
||||
timer.start()
|
||||
|
||||
|
||||
func setup_timer() -> void:
|
||||
timer = Timer.new()
|
||||
timer.wait_time = shoot_interval
|
||||
timer.one_shot = false
|
||||
timer.autostart = true
|
||||
timer.timeout.connect(on_timer_timeout)
|
||||
add_child(timer)
|
@@ -15,6 +15,5 @@ func on_collected(amount: int) -> void:
|
||||
return
|
||||
|
||||
game_manager.add_coins(amount)
|
||||
print("Coins: ", game_manager.get_coins())
|
||||
# todo: play sound
|
||||
# todo: update ui
|
||||
|
82
scripts/components/side_to_side_movement.gd
Normal file
82
scripts/components/side_to_side_movement.gd
Normal file
@@ -0,0 +1,82 @@
|
||||
class_name SideToSideMovement
|
||||
extends Node
|
||||
|
||||
@export var root: Node2D
|
||||
@export var sprite2d: Sprite2D
|
||||
@export var speed: float = 10.0
|
||||
@export var wait_time: float = 1.0
|
||||
@export var left_ray: RayCast2D
|
||||
@export var right_ray: RayCast2D
|
||||
|
||||
var direction: Vector2 = Vector2.LEFT
|
||||
var new_direction: Vector2 = Vector2.LEFT
|
||||
var timer: Timer
|
||||
var triggered_direction_change: bool = false
|
||||
|
||||
signal direction_changed()
|
||||
|
||||
func _ready() -> void:
|
||||
root = get_parent()
|
||||
|
||||
if not sprite2d:
|
||||
print("SideToSideMovement node missing Sprite2D child.")
|
||||
return
|
||||
|
||||
if not left_ray or not right_ray:
|
||||
print("SideToSideMovement node missing RayCast2D children.")
|
||||
return
|
||||
|
||||
setup_timer()
|
||||
direction_changed.connect(on_direction_changed)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
handle_direction()
|
||||
handle_sprite_flip()
|
||||
handle_movement(delta)
|
||||
|
||||
func handle_direction() -> void:
|
||||
# we are not colliding with anything, which means we don't have ground to walk on. Stop moving.
|
||||
if not left_ray.is_colliding() and not right_ray.is_colliding():
|
||||
new_direction = Vector2.ZERO
|
||||
return
|
||||
|
||||
# If the left ray is not colliding and the right ray is colliding, that means we have ground to the right and we should change direction to the right.
|
||||
if not left_ray.is_colliding() and right_ray.is_colliding():
|
||||
new_direction = Vector2.RIGHT
|
||||
direction_changed.emit()
|
||||
return
|
||||
if not right_ray.is_colliding() and left_ray.is_colliding():
|
||||
new_direction = Vector2.LEFT
|
||||
direction_changed.emit()
|
||||
return
|
||||
|
||||
func handle_sprite_flip() -> void:
|
||||
if direction == Vector2.LEFT:
|
||||
sprite2d.flip_h = true
|
||||
else:
|
||||
sprite2d.flip_h = false
|
||||
|
||||
func handle_movement(delta: float) -> void:
|
||||
root.position += direction * speed * delta
|
||||
|
||||
func on_direction_changed() -> void:
|
||||
if direction == new_direction or triggered_direction_change:
|
||||
return
|
||||
triggered_direction_change = true
|
||||
direction = Vector2.ZERO
|
||||
timer.start()
|
||||
|
||||
func on_timer_timeout() -> void:
|
||||
timer.stop()
|
||||
direction = new_direction
|
||||
triggered_direction_change = false
|
||||
|
||||
|
||||
func setup_timer() -> void:
|
||||
timer = Timer.new()
|
||||
add_child(timer)
|
||||
timer.wait_time = wait_time
|
||||
timer.one_shot = true
|
||||
timer.timeout.connect(on_timer_timeout)
|
||||
|
Reference in New Issue
Block a user