extends RigidBody2D signal reset @export var spin_speed = -1 @export var move_speed = 60 @export var power_magnitude = 10 @export var drag_radius = 30 var start_position: Vector2 var start_minimum = drag_radius @onready var start_maximum = $"../Hoop".position.x - 40 var is_dragging = false var waiting_for_shoot = true var mouse_over_ball = false var phase = 1 var phase_increment = [5, 15, 25, 35, 45, 55] func _ready(): start_position = global_position # This function toggles between dragging the ball for a shot and allowing the physics engine to move # the ball, setting any necessary properties along the way. func toggle_mode(): if waiting_for_shoot: waiting_for_shoot = false var shoot_power = -$Sprite2D.position * power_magnitude apply_impulse(shoot_power, Vector2(2, 2)) var shootAngle = atan2($Sprite2D.position.y, $Sprite2D.position.x) $ReleaseIndicator.visible = false $ReleaseIndicator.position = $Sprite2D.position $ReleaseIndicator.rotation = shootAngle - PI / 2 is_dragging = false $GhostSprite.visible = false $Sprite2D.position = Vector2(0, 0) else: sleeping = false # Adds offset of ball's rotation to sprite AFTER the entire object has rotated from physics. # Done to keep appearance of same rotation to add consistency when resetting the ball. $Sprite2D.rotation += rotation # Hide the release indicator for the first throw in the next round if !$"../Hoop".has_scored: $ReleaseIndicator.visible = true waiting_for_shoot = true emit_signal("reset") set_use_custom_integrator(waiting_for_shoot) # Override the default physics when we want to manually set the position and rotation. func _integrate_forces(state): if waiting_for_shoot: state.transform = Transform2D(0, start_position) state.linear_velocity = Vector2() state.angular_velocity = 0 func _process(delta): if waiting_for_shoot: $Sprite2D.rotation += spin_speed * delta $GhostSprite.rotation += spin_speed * delta func _input(event): if event.is_action_pressed("shoot") and mouse_over_ball and waiting_for_shoot: is_dragging = true $Sprite2D.position = get_global_mouse_position() - start_position $GhostSprite.visible = true $GhostSprite.rotation = $Sprite2D.rotation if is_dragging and event is InputEventMouseMotion: $Sprite2D.position = get_global_mouse_position() - start_position # If the mouse pointer is beyond a certain radius, don't move the sprite any further from # the start position while still keeping it at the same angle as the mouse pointer. var hypot = sqrt(pow($Sprite2D.position.x, 2) + pow($Sprite2D.position.y, 2)) if hypot > drag_radius: var angle = atan2($Sprite2D.position.y, $Sprite2D.position.x) $Sprite2D.position = Vector2(cos(angle), sin(angle)) * drag_radius if event.is_action_released("shoot"): if !waiting_for_shoot or is_dragging: toggle_mode() func _on_InnerShape_mouse_entered(): mouse_over_ball = true func _on_InnerShape_mouse_exited(): mouse_over_ball = false func position_changer(): # Progressive if phase == 1: start_position.x -= 20 start_position.x = clamp(start_position.x, start_minimum, start_maximum) # Random if phase == 2: start_position.x = randf_range(start_minimum, start_maximum) func _on_Hoop_score(): if global_variables.score >= phase_increment[0] and global_variables.score < phase_increment[1]: phase = 2 if global_variables.score >= phase_increment[1] and global_variables.score < phase_increment[2]: start_minimum = (drag_radius * 2) + $"../Camera2D".limit_left phase = 1 if global_variables.score >= phase_increment[2] and global_variables.score < phase_increment[3]: phase = 2 position_changer() func _on_body_entered(_body): $"/root/Audio".impact_noise(abs($"/root/Node2D/Basketball".get_linear_velocity()))