Add new level, collapsable component, knockback component
This commit is contained in:
55
scripts/components/collapsable.gd
Normal file
55
scripts/components/collapsable.gd
Normal file
@@ -0,0 +1,55 @@
|
||||
class_name CollapsableComponent
|
||||
extends Node
|
||||
|
||||
@export var to_collapse_timer: Timer
|
||||
@export var reset_timer: Timer
|
||||
@export var sprite2d: Sprite2D
|
||||
@export var collision_shape: CollisionShape2D
|
||||
|
||||
@export var collapse_time: float = 0.5
|
||||
@export var reset_time: float = 1.0
|
||||
|
||||
@export var anim_time: float = 0.25
|
||||
|
||||
func _ready() -> void:
|
||||
reset_timers()
|
||||
|
||||
func _on_to_collapse_timer_timeout() -> void:
|
||||
collapse_bridge()
|
||||
|
||||
func _on_reset_timer_timeout() -> void:
|
||||
reactivate_bridge()
|
||||
|
||||
func collapse_bridge():
|
||||
to_collapse_timer.stop()
|
||||
to_collapse_timer.wait_time = collapse_time
|
||||
|
||||
var bridge_tween = create_tween()
|
||||
bridge_tween.tween_property(sprite2d, "modulate:a", 0, anim_time)
|
||||
await bridge_tween.finished
|
||||
|
||||
collision_shape.disabled = true
|
||||
reset_timer.start()
|
||||
|
||||
func reactivate_bridge():
|
||||
reset_timer.stop()
|
||||
reset_timer.wait_time = reset_time
|
||||
|
||||
var bridge_tween = create_tween()
|
||||
bridge_tween.tween_property(sprite2d, "modulate:a", 1, anim_time)
|
||||
await bridge_tween.finished
|
||||
|
||||
collision_shape.disabled = false
|
||||
|
||||
func _on_collapsable_detector_body_entered(_body: Node2D) -> void:
|
||||
to_collapse_timer.start()
|
||||
|
||||
func reset_timers():
|
||||
to_collapse_timer.stop()
|
||||
to_collapse_timer.wait_time = collapse_time
|
||||
|
||||
|
||||
func _on_collapsable_detector_body_exited(_body: Node2D) -> void:
|
||||
var collapse_time_left: float = abs(to_collapse_timer.time_left - collapse_time)
|
||||
if collapse_time_left < (0.1 * collapse_time):
|
||||
reset_timers()
|
@@ -9,14 +9,14 @@ var root: Node
|
||||
signal collected(amount: int)
|
||||
|
||||
func _ready() -> void:
|
||||
if area2d:
|
||||
area2d.body_entered.connect(_on_area2d_body_entered)
|
||||
else:
|
||||
print("Collectable node missing Area2D child.")
|
||||
if area2d:
|
||||
area2d.body_entered.connect(_on_area2d_body_entered)
|
||||
else:
|
||||
print("Collectable node missing Area2D child.")
|
||||
|
||||
root = get_parent()
|
||||
root = get_parent()
|
||||
|
||||
func _on_area2d_body_entered(body: Node2D) -> void:
|
||||
if body.has_node("CanPickUpComponent"):
|
||||
collected.emit(collectable_data.amount)
|
||||
root.queue_free()
|
||||
if body.has_node("CanPickUpComponent"):
|
||||
collected.emit(collectable_data.amount)
|
||||
root.queue_free()
|
||||
|
@@ -1,7 +1,20 @@
|
||||
class_name DamageComponent
|
||||
extends Node2D
|
||||
extends Node
|
||||
|
||||
@export var damage: float = 0.25
|
||||
@export var area2d: Area2D
|
||||
|
||||
func _ready() -> void:
|
||||
if not area2d:
|
||||
printerr("No area2d assigned!")
|
||||
return
|
||||
|
||||
area2d.body_entered.connect(on_area2d_body_entered)
|
||||
|
||||
func deal_damage(target: HealthComponent):
|
||||
target.decrease_health(damage)
|
||||
|
||||
func on_area2d_body_entered(body: Node2D):
|
||||
if body.has_node("HealthComponent"):
|
||||
var health_component: HealthComponent = body.get_node("HealthComponent")
|
||||
deal_damage(health_component)
|
||||
|
@@ -1,10 +1,10 @@
|
||||
class_name HealthComponent
|
||||
extends Node2D
|
||||
extends Node
|
||||
|
||||
@export var health: float = 1.0
|
||||
@export var max_health: float = 1.0
|
||||
|
||||
signal on_health_change(delta: float)
|
||||
signal on_health_change(delta: float, total_health: float)
|
||||
signal on_death
|
||||
|
||||
func _get_delta(value: float) -> float:
|
||||
@@ -16,7 +16,7 @@ func set_health(new_value: float):
|
||||
|
||||
if new_value >= max_health:
|
||||
health = max_health
|
||||
on_health_change.emit(delta)
|
||||
on_health_change.emit(delta, health)
|
||||
return
|
||||
|
||||
health = new_value
|
||||
@@ -25,7 +25,7 @@ func set_health(new_value: float):
|
||||
on_death.emit()
|
||||
return
|
||||
|
||||
on_health_change.emit(delta)
|
||||
on_health_change.emit(delta, health)
|
||||
|
||||
func decrease_health(value: float):
|
||||
var delta = _get_delta(value)
|
||||
@@ -36,7 +36,7 @@ func decrease_health(value: float):
|
||||
on_death.emit()
|
||||
return
|
||||
|
||||
on_health_change.emit(delta)
|
||||
on_health_change.emit(delta, health)
|
||||
|
||||
func increase_health(value: float):
|
||||
var delta = _get_delta(value)
|
||||
@@ -45,9 +45,9 @@ func increase_health(value: float):
|
||||
|
||||
if health >= max_health:
|
||||
health = max_health
|
||||
on_health_change.emit(delta)
|
||||
on_health_change.emit(delta, health)
|
||||
return
|
||||
|
||||
health += value
|
||||
on_health_change.emit(delta)
|
||||
on_health_change.emit(delta, health)
|
||||
|
||||
|
32
scripts/components/knockback.gd
Normal file
32
scripts/components/knockback.gd
Normal file
@@ -0,0 +1,32 @@
|
||||
class_name KnockbackComponent
|
||||
extends Node
|
||||
|
||||
@export var character_body: CharacterBody2D
|
||||
@export var knockback_force: float = 25.0
|
||||
|
||||
var knockback_mode: bool = false
|
||||
var knockback_frames: int = 0
|
||||
|
||||
func apply_knockback(force: float, delta: float) -> void:
|
||||
var velocity = character_body.velocity.normalized()
|
||||
var knockback_dir = Vector2(sign(velocity.x) * 1.0, 0.4)
|
||||
var knockback_vector = -knockback_dir * force * delta
|
||||
character_body.velocity += knockback_vector
|
||||
|
||||
func _on_health_component_on_health_change(delta: float, total_health: float) -> void:
|
||||
if total_health <= 0.0 and delta < 0.0:
|
||||
return
|
||||
knockback_mode = true
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if knockback_mode:
|
||||
knockback_frames += 1
|
||||
if knockback_frames > 1:
|
||||
knockback_mode = false
|
||||
knockback_frames = 0
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if knockback_mode:
|
||||
apply_knockback(knockback_force, delta)
|
||||
|
||||
|
9
scripts/components/player_death.gd
Normal file
9
scripts/components/player_death.gd
Normal file
@@ -0,0 +1,9 @@
|
||||
class_name PlayerDeathComponent
|
||||
extends Node
|
||||
|
||||
func reset_scene() -> void:
|
||||
get_tree().reload_current_scene()
|
||||
|
||||
func _on_health_component_on_death() -> void:
|
||||
# todo: play audio on death
|
||||
call_deferred("reset_scene")
|
@@ -4,17 +4,17 @@ extends Node
|
||||
@onready var game_manager: GM = $"/root/GameManager"
|
||||
|
||||
func _ready():
|
||||
await get_tree().process_frame
|
||||
var coins = get_tree().get_nodes_in_group("coins")
|
||||
|
||||
for coin in coins:
|
||||
coin.connect("collected", on_collected)
|
||||
await get_tree().process_frame
|
||||
var coins = get_tree().get_nodes_in_group("coins")
|
||||
|
||||
for coin in coins:
|
||||
coin.connect("collected", on_collected)
|
||||
|
||||
func on_collected(amount: int) -> void:
|
||||
if not game_manager:
|
||||
return
|
||||
if not game_manager:
|
||||
return
|
||||
|
||||
game_manager.add_coins(amount)
|
||||
print("Coins: ", game_manager.get_coins())
|
||||
# todo: play sound
|
||||
# todo: update ui
|
||||
game_manager.add_coins(amount)
|
||||
print("Coins: ", game_manager.get_coins())
|
||||
# todo: play sound
|
||||
# todo: update ui
|
||||
|
Reference in New Issue
Block a user