Refactor brick throwing mechanics; integrate new input handling and projectile initialization components

This commit is contained in:
2025-05-13 00:44:44 +02:00
parent 3d65daf0c5
commit c291f42531
25 changed files with 276 additions and 72 deletions

View File

@@ -5,7 +5,7 @@ extends Node
@export var fire_rate: float = 1.0
@export var player_controller: PlayerController
@export var timer: Timer
@export var charge_throw_component: ChargeThrowComponent
@export var throw_input_behavior: ThrowInputResource
var can_throw: bool = true
@@ -14,14 +14,18 @@ func _ready() -> void:
setup_timer()
can_throw = true
if throw_input_behavior:
throw_input_behavior.throw_requested.connect(throw_brick)
func _input(event: InputEvent) -> void:
if event.is_action_pressed("attack") and can_throw and charge_throw_component:
charge_throw_component.start_charging()
if throw_input_behavior:
throw_input_behavior.process_input(event)
if event.is_action_released("attack") and can_throw and charge_throw_component:
var power_multiplier: float = charge_throw_component.stop_charging()
throw_brick(power_multiplier)
func _process(delta: float) -> void:
if throw_input_behavior:
throw_input_behavior.update(delta)
func setup_timer() -> void:
@@ -36,18 +40,17 @@ func on_timer_timeout() -> void:
func throw_brick(power_multiplier: float = 1.0) -> void:
var brick_instance: Node2D = brick_scene.instantiate()
var instance: Node2D = brick_scene.instantiate()
var init := instance.get_node_or_null("ProjectileInitComponent") as ProjectileInitComponent
if init:
init.initialize({
"position": player_controller.global_position,
"rotation": player_controller.rotation,
"direction": player_controller.last_direction,
"power_multiplier": power_multiplier
})
var launch_component := brick_instance.get_node_or_null("LaunchComponent") as LaunchComponent
var chargable_component := brick_instance.get_node_or_null("ChargableComponent") as ChargableComponent
if launch_component:
launch_component.initial_direction = player_controller.last_direction
launch_component.spawn_position = player_controller.global_position
launch_component.spawn_rotation = player_controller.rotation
launch_component.speed *= power_multiplier if chargable_component else 1.0
brick_instance.global_position = player_controller.global_position
get_tree().current_scene.add_child(brick_instance)
get_tree().current_scene.add_child(instance)
can_throw = false
timer.start()
timer.start()

View File

@@ -1,2 +0,0 @@
class_name ChargableComponent
extends Node

View File

@@ -1 +0,0 @@
uid://ciowd622nk0i7

View File

@@ -0,0 +1,20 @@
class_name ProjectileInitComponent
extends Node
@export var launch_component: LaunchComponent
func initialize(params: Dictionary) -> void:
var position := params.get("position", Vector2.ZERO) as Vector2
var direction := params.get("direction", Vector2.RIGHT) as Vector2
var rotation := params.get("rotation", 0.0) as float
var power := params.get("power_multiplier", 1.0) as float
owner.global_position = position
owner.global_rotation = rotation
if launch_component:
launch_component.initial_direction = direction
launch_component.spawn_position = position
launch_component.spawn_rotation = rotation
launch_component.speed *= power

View File

@@ -0,0 +1 @@
uid://bgty7040ams6s

View File

@@ -0,0 +1,56 @@
class_name ChargeThrowInputResource
extends ThrowInputResource
@export var min_power := 0.5
@export var max_power := 2.0
@export var max_charge_time := 1.5
@export var min_charge_duration := 0.1
var is_charging := false
var charge_start_time := 0.0
signal charge_started
signal charge_updated(charge_ratio: float)
signal charge_stopped
func process_input(event: InputEvent) -> void:
if event.is_action_pressed("attack"):
is_charging = true
charge_start_time = Time.get_ticks_msec() / 1000.0
emit_signal("charge_started")
if event.is_action_released("attack") and is_charging:
var power := _calculate_power()
is_charging = false
emit_signal("throw_requested", power)
emit_signal("charge_stopped")
func _calculate_power() -> float:
var now := Time.get_ticks_msec() / 1000.0
var held_time := now - charge_start_time
if held_time < min_charge_duration:
return min_power
var t = clamp(held_time / max_charge_time, 0.0, 1.0)
return lerp(min_power, max_power, t)
func get_charge_ratio() -> float:
if not is_charging:
return min_power
var now := Time.get_ticks_msec() / 1000.0
var held := now - charge_start_time
var t = clamp(held / max_charge_time, 0.0, 1.0)
return lerp(min_power, max_power, t)
func update(_delta: float) -> void:
if not is_charging:
return
var t = clamp(get_charge_ratio(), min_power, max_power)
emit_signal("charge_updated", t)
func supports_charging() -> bool:
return true

View File

@@ -0,0 +1 @@
uid://dl1kpll33o6mv

View File

@@ -0,0 +1,6 @@
class_name TapThrowInputResource
extends ThrowInputResource
func process_input(event: InputEvent) -> void:
if event.is_action_pressed("attack"):
throw_requested.emit(1.0)

View File

@@ -0,0 +1 @@
uid://blvdnsyi287rf

View File

@@ -0,0 +1,16 @@
class_name ThrowInputResource
extends Resource
signal throw_requested(power_multiplier: float)
func process_input(event: InputEvent) -> void:
pass
func update(delta: float) -> void:
pass
func supports_charging() -> bool:
return false

View File

@@ -0,0 +1 @@
uid://cry02xehijy2v

View File

@@ -32,7 +32,7 @@ func add_skill(skill_data: SkillData) -> void:
skill_instance[key] = value
add_child(skill_instance)
owner.add_child(skill_instance)
active_components[skill_data.name] = skill_instance

View File

@@ -1,22 +1,18 @@
extends Node
@export var progress_bar: ProgressBar
@export var charge_throw_component: ChargeThrowComponent
@export var brick_throw_component: BrickThrowComponent
var throw_input: ChargeThrowInputResource
func _ready() -> void:
if not charge_throw_component:
return
owner.child_entered_tree.connect(on_nodes_changed)
if not progress_bar:
return
if progress_bar:
progress_bar.hide()
setup_progress_bar()
progress_bar.hide()
charge_throw_component.charge_started.connect(on_charge_started)
charge_throw_component.charge_updated.connect(on_charge_updated)
charge_throw_component.charge_stopped.connect(on_charge_stopped)
setup_dependencies()
func on_charge_updated(charge_ratio: float) -> void:
@@ -45,8 +41,41 @@ func setup_progress_bar() -> void:
if not progress_bar:
return
progress_bar.min_value = charge_throw_component.min_power
progress_bar.max_value = charge_throw_component.max_power
progress_bar.value = charge_throw_component.min_power
progress_bar.min_value = throw_input.min_power
progress_bar.max_value = throw_input.max_power
progress_bar.value = throw_input.min_power
progress_bar.step = 0.01
progress_bar.show()
progress_bar.hide()
func setup_dependencies() -> void:
if not brick_throw_component:
return
if brick_throw_component.throw_input_behavior is ChargeThrowInputResource:
throw_input = brick_throw_component.throw_input_behavior as ChargeThrowInputResource
else:
throw_input = null
if not throw_input:
return
if not progress_bar:
return
if not throw_input.supports_charging():
progress_bar.hide()
return
setup_progress_bar()
throw_input.charge_started.connect(on_charge_started)
throw_input.charge_updated.connect(on_charge_updated)
throw_input.charge_stopped.connect(on_charge_stopped)
func on_nodes_changed(node: Node) -> void:
if node is BrickThrowComponent and brick_throw_component == null:
brick_throw_component = node as BrickThrowComponent
setup_dependencies()
return