72 lines
2.3 KiB
GDScript
72 lines
2.3 KiB
GDScript
extends RigidBody2D
|
|
|
|
@onready var hurtbox: Area2D = $HurtArea2D
|
|
@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
|
|
|
|
@export var launch_speed: Vector2 = Vector2(150, 250)
|
|
@export var speed_mult: float = 1.08
|
|
|
|
var current_decel_tween: Tween = null
|
|
var is_hit: bool = false
|
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
func _ready() -> void:
|
|
#connect("body_entered", _on_collision)
|
|
hurtbox.connect("area_entered", _on_hit)
|
|
|
|
launch()
|
|
|
|
|
|
func launch(angle: float = 0, speed_override: float = 0) -> void:
|
|
angle = randf_range(-PI/3, PI/3) + PI * float(randi()%2) if angle == 0 else angle
|
|
linear_velocity = Vector2(cos(angle), sin(angle)) * (randf_range(launch_speed.x, launch_speed.y) if speed_override == 0 else speed_override)
|
|
var length: float = linear_velocity.length()/100
|
|
play_animation(length)
|
|
decelerate_to_stop(length*2)
|
|
|
|
|
|
func play_animation(speed_scale: float = 0) -> void:
|
|
assert(speed_scale != 0, "speed_scale is zero for aniumation")
|
|
sprite.speed_scale = speed_scale * (1 if randi()%2 == 0 else -1)
|
|
sprite.play("default")
|
|
|
|
|
|
func decelerate_to_stop(duration: float = 0.3) -> void: # Call this after collision
|
|
# KILL ANY EXISTING TWEEN (one at a time guaranteed!)
|
|
if current_decel_tween:
|
|
current_decel_tween.kill()
|
|
|
|
# CREATE NEW ONE
|
|
current_decel_tween = create_tween()
|
|
current_decel_tween.tween_property(sprite, "speed_scale", 0.0, duration)
|
|
current_decel_tween.tween_callback(func() -> void:
|
|
sprite.pause() # Freeze on last frame
|
|
current_decel_tween = null # Clean up
|
|
)
|
|
|
|
|
|
func _on_hit(hitbox: Hit) -> void:
|
|
print("area detected")
|
|
if not is_hit:
|
|
if hitbox.is_in_group("hit"):
|
|
assert(hitbox.power_hit != null, "hit doesnt have correct metadata, is it a hit?")
|
|
print("ball not hit yet")
|
|
var player: Player = hitbox.get_parent()
|
|
var timer: Timer = player.hit_timer
|
|
var angle: float = randf_range(3*PI/4, PI/4) * (-1 if player.id == 1 else 1)
|
|
var speed: float = randf_range(300, 350) if hitbox.power_hit else 0.0 # o.o
|
|
launch(angle, speed)
|
|
print("ball hit")
|
|
if not timer.is_connected("timeout", _on_hit_end):
|
|
timer.connect("timeout", _on_hit_end)
|
|
EventBus.ball_hit.emit(player.id, linear_velocity)
|
|
is_hit = true
|
|
|
|
|
|
func _on_hit_end() -> void:
|
|
is_hit = false
|
|
|
|
func _on_collision(_body: Node) -> void:
|
|
var length: float = linear_velocity.length()/100
|
|
play_animation(length)
|
|
decelerate_to_stop(length)
|