Add charge throw mechanics; refactor bullet and brick components
This commit is contained in:
@@ -5,35 +5,50 @@ extends Node
|
||||
@export var fire_rate: float = 1.0
|
||||
@export var player_controller: PlayerController
|
||||
@export var timer: Timer
|
||||
@export var charge_throw_component: ChargeThrowComponent
|
||||
|
||||
var can_throw: bool = true
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
setup_timer()
|
||||
can_throw = true
|
||||
|
||||
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("attack") and can_throw:
|
||||
throw_brick()
|
||||
|
||||
if event.is_action_pressed("attack") and can_throw and charge_throw_component:
|
||||
charge_throw_component.start_charging()
|
||||
|
||||
if event.is_action_released("attack") and can_throw and charge_throw_component:
|
||||
var power_multiplier: float = charge_throw_component.stop_charging()
|
||||
print("Power Multiplier: ", power_multiplier)
|
||||
throw_brick(power_multiplier)
|
||||
|
||||
|
||||
func setup_timer() -> void:
|
||||
timer.wait_time = fire_rate
|
||||
timer.one_shot = false
|
||||
timer.autostart = false
|
||||
timer.timeout.connect(on_timer_timeout)
|
||||
|
||||
|
||||
|
||||
func on_timer_timeout() -> void:
|
||||
can_throw = true
|
||||
|
||||
|
||||
func throw_brick() -> void:
|
||||
|
||||
|
||||
func throw_brick(power_multiplier: float = 1.0) -> void:
|
||||
var brick_instance: Node2D = brick_scene.instantiate()
|
||||
var brick: BulletComponent = brick_instance.get_node("BulletComponent")
|
||||
brick_instance.position = player_controller.position
|
||||
brick.direction = player_controller.last_direction
|
||||
|
||||
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)
|
||||
|
||||
|
||||
can_throw = false
|
||||
timer.start()
|
||||
|
@@ -1,40 +0,0 @@
|
||||
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)
|
||||
area2d.area_entered.connect(on_area2d_area_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_area2d_area_entered(_area: Area2D) -> void:
|
||||
root.queue_free()
|
||||
|
||||
|
||||
func on_timer_timeout() -> void:
|
||||
root.queue_free()
|
@@ -1 +0,0 @@
|
||||
uid://bh2vrkdbrtpin
|
18
scripts/components/bullet_component.gd
Normal file
18
scripts/components/bullet_component.gd
Normal file
@@ -0,0 +1,18 @@
|
||||
class_name BulletComponent
|
||||
extends Node
|
||||
|
||||
@export var root: Node2D
|
||||
@export var area2d: Area2D
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
area2d.body_entered.connect(on_area2d_body_entered)
|
||||
area2d.area_entered.connect(on_area2d_area_entered)
|
||||
|
||||
|
||||
func on_area2d_body_entered(_body: Node2D) -> void:
|
||||
root.queue_free()
|
||||
|
||||
|
||||
func on_area2d_area_entered(_area: Area2D) -> void:
|
||||
root.queue_free()
|
1
scripts/components/bullet_component.gd.uid
Normal file
1
scripts/components/bullet_component.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cdnwrn8v05qhi
|
2
scripts/components/chargable_component.gd
Normal file
2
scripts/components/chargable_component.gd
Normal file
@@ -0,0 +1,2 @@
|
||||
class_name ChargableComponent
|
||||
extends Node
|
1
scripts/components/chargable_component.gd.uid
Normal file
1
scripts/components/chargable_component.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://ciowd622nk0i7
|
45
scripts/components/charge_throw_component.gd
Normal file
45
scripts/components/charge_throw_component.gd
Normal file
@@ -0,0 +1,45 @@
|
||||
class_name ChargeThrowComponent
|
||||
extends Node
|
||||
|
||||
@export var min_power: float = 0.5
|
||||
@export var max_power: float = 2.0
|
||||
@export var max_charge_time: float = 1.5
|
||||
|
||||
var charge_start_time: float = 0.0
|
||||
var is_charging: bool = false
|
||||
signal charge_started
|
||||
signal charge_updated(charge_ratio: float)
|
||||
signal charge_stopped
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if not is_charging:
|
||||
return
|
||||
|
||||
var charge_ratio := get_charge_ratio()
|
||||
charge_updated.emit(charge_ratio)
|
||||
|
||||
|
||||
func start_charging() -> void:
|
||||
is_charging = true
|
||||
charge_start_time = Time.get_ticks_msec() / 1000.0
|
||||
charge_started.emit()
|
||||
|
||||
|
||||
func get_charge_ratio() -> float:
|
||||
if not is_charging:
|
||||
return 0.0
|
||||
|
||||
var held_time := (Time.get_ticks_msec() / 1000.0) - charge_start_time
|
||||
var t = clamp(held_time / max_charge_time, 0.0, 1.0)
|
||||
|
||||
return lerp(min_power, max_power, t)
|
||||
|
||||
|
||||
func stop_charging() -> float:
|
||||
is_charging = false
|
||||
var held_time := (Time.get_ticks_msec() / 1000.0) - charge_start_time
|
||||
var t = clamp(held_time / max_charge_time, 0.0, 1.0)
|
||||
charge_start_time = 0.0
|
||||
charge_stopped.emit()
|
||||
return lerp(min_power, max_power, t)
|
1
scripts/components/charge_throw_component.gd.uid
Normal file
1
scripts/components/charge_throw_component.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c6fclevp3peuo
|
30
scripts/components/gravity_motion_component.gd
Normal file
30
scripts/components/gravity_motion_component.gd
Normal file
@@ -0,0 +1,30 @@
|
||||
class_name GravityMotionComponent
|
||||
extends Node2D
|
||||
|
||||
@export var character_body: CharacterBody2D
|
||||
@export var launch_component: LaunchComponent
|
||||
@export var gravity: Vector2 = Vector2(0, 980.0)
|
||||
@export var target_direction: Vector2 = Vector2(1.0, -1.0)
|
||||
|
||||
var velocity: Vector2 = Vector2.ZERO
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if not launch_component:
|
||||
return
|
||||
var direction := target_direction if launch_component.initial_direction.x > 0 else Vector2(-target_direction.x, target_direction.y)
|
||||
direction = direction.normalized()
|
||||
velocity = direction * launch_component.speed
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if not character_body:
|
||||
return
|
||||
|
||||
velocity += gravity * delta
|
||||
character_body.velocity = velocity
|
||||
|
||||
character_body.move_and_slide()
|
||||
|
||||
if velocity.length_squared() > 0.01:
|
||||
character_body.rotation = velocity.angle()
|
1
scripts/components/gravity_motion_component.gd.uid
Normal file
1
scripts/components/gravity_motion_component.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c2gbumw4x4t1v
|
17
scripts/components/launch_component.gd
Normal file
17
scripts/components/launch_component.gd
Normal file
@@ -0,0 +1,17 @@
|
||||
class_name LaunchComponent
|
||||
extends Node2D
|
||||
|
||||
@export var root: Node2D
|
||||
@export var initial_direction: Vector2 = Vector2.RIGHT
|
||||
@export var speed: float = 16.0
|
||||
@export var spawn_position: Vector2 = Vector2.ZERO
|
||||
@export var spawn_rotation: float = 0.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
root.global_position = spawn_position
|
||||
root.global_rotation = spawn_rotation
|
||||
|
||||
|
||||
func get_initial_velocity() -> Vector2:
|
||||
return initial_direction.normalized() * speed
|
1
scripts/components/launch_component.gd.uid
Normal file
1
scripts/components/launch_component.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://873un8agkyja
|
22
scripts/components/lifetime_component.gd
Normal file
22
scripts/components/lifetime_component.gd
Normal file
@@ -0,0 +1,22 @@
|
||||
class_name LifetimeComponent
|
||||
extends Node
|
||||
|
||||
@export var root: Node
|
||||
@export var life_time: float = 5.0
|
||||
@export var timer: Timer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if not root:
|
||||
printerr("Root node not set.")
|
||||
return
|
||||
|
||||
if not timer:
|
||||
printerr("Timer node not set.")
|
||||
return
|
||||
|
||||
timer.timeout.connect(on_timer_timeout)
|
||||
|
||||
|
||||
func on_timer_timeout() -> void:
|
||||
root.queue_free()
|
1
scripts/components/lifetime_component.gd.uid
Normal file
1
scripts/components/lifetime_component.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bvsgg8lu0a8m6
|
21
scripts/components/out_of_screen_component.gd
Normal file
21
scripts/components/out_of_screen_component.gd
Normal file
@@ -0,0 +1,21 @@
|
||||
class_name OutOfScreenComponent
|
||||
extends Node
|
||||
|
||||
@export var visibility_notifier: VisibleOnScreenNotifier2D
|
||||
@export var root: Node
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if not visibility_notifier:
|
||||
printerr("Visibility notifier not set.")
|
||||
return
|
||||
|
||||
visibility_notifier.screen_exited.connect(_on_screen_exited)
|
||||
|
||||
|
||||
func _on_screen_exited() -> void:
|
||||
if not root:
|
||||
printerr("Root node not set.")
|
||||
return
|
||||
|
||||
root.queue_free()
|
1
scripts/components/out_of_screen_component.gd.uid
Normal file
1
scripts/components/out_of_screen_component.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://1tnr46o1ib4u
|
@@ -27,10 +27,14 @@ func shoot() -> void:
|
||||
return
|
||||
|
||||
var bullet_instance: Node2D = bullet_scene.instantiate()
|
||||
var bullet_component: BulletComponent = bullet_instance.get_node("BulletComponent")
|
||||
var launch_component: LaunchComponent = bullet_instance.get_node_or_null("LaunchComponent")
|
||||
var spawn_position: Vector2 = bullet_spawn_right.global_position if shoot_direction == Vector2.RIGHT else bullet_spawn_left.global_position
|
||||
if launch_component:
|
||||
launch_component.initial_direction = shoot_direction
|
||||
launch_component.spawn_position = spawn_position
|
||||
launch_component.spawn_rotation = root.rotation
|
||||
|
||||
bullet_instance.position = spawn_position
|
||||
bullet_component.direction = shoot_direction
|
||||
get_tree().current_scene.add_child(bullet_instance)
|
||||
|
||||
|
||||
|
21
scripts/components/projectile_component.gd
Normal file
21
scripts/components/projectile_component.gd
Normal file
@@ -0,0 +1,21 @@
|
||||
class_name ProjectileComponent
|
||||
extends Node2D
|
||||
|
||||
@export var speed: float = 16.0
|
||||
@export var dir: float
|
||||
@export var spawn_position: Vector2
|
||||
@export var spawn_rotation: float
|
||||
@export var character_body: CharacterBody2D
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
global_position = spawn_position
|
||||
global_rotation = spawn_rotation
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if not character_body:
|
||||
return
|
||||
|
||||
character_body.velocity = Vector2(0, -speed).rotated(dir)
|
||||
character_body.move_and_slide()
|
1
scripts/components/projectile_component.gd.uid
Normal file
1
scripts/components/projectile_component.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bk2fvcv0g4x1q
|
9
scripts/components/straight_motion_component.gd
Normal file
9
scripts/components/straight_motion_component.gd
Normal file
@@ -0,0 +1,9 @@
|
||||
class_name StraightMotionComponent
|
||||
extends Node
|
||||
|
||||
@export var root: Node2D
|
||||
@export var launch_component: LaunchComponent
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
root.position += launch_component.get_initial_velocity() * delta
|
1
scripts/components/straight_motion_component.gd.uid
Normal file
1
scripts/components/straight_motion_component.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cvcnfrr1udco5
|
Reference in New Issue
Block a user