1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
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()))
|