extends Node2D var launch_speed := -35 var flipper_launch_speed := Vector2( 1.0, -30, ) var shake_tween: Tween var camera_base_position: Vector2 func _ready() -> void: shake_tween = get_tree().create_tween() shake_tween.kill() camera_base_position = $Camera2D.position $FlipperLeft.rotation_degrees = 30 $FlipperRight.rotation_degrees = -30 launch_ball() func _process(_delta: float) -> void: if Input.is_action_pressed("flipper_left"): var tween := get_tree().create_tween() tween.tween_property($FlipperLeft, "rotation_degrees", -45, 0.1) if Input.is_action_just_released("flipper_left"): var tween := get_tree().create_tween() tween.tween_property($FlipperLeft, "rotation_degrees", 30, 0.1) if Input.is_action_just_pressed("flipper_left"): if $FlipperLeft.is_colliding(%Ball): if %Ball.position.y < $FlipperLeft.get_lowest_point().y: %Ball.apply_central_impulse( Vector2(abs(%Ball.global_position.x - $FlipperLeft.get_center().x), 1.0) * flipper_launch_speed ) if Input.is_action_pressed("flipper_right"): var tween := get_tree().create_tween() tween.tween_property($FlipperRight, "rotation_degrees", 45, 0.1) if Input.is_action_just_released("flipper_right"): var tween := get_tree().create_tween() tween.tween_property($FlipperRight, "rotation_degrees", -30, 0.1) if Input.is_action_just_pressed("flipper_right"): if $FlipperRight.is_colliding(%Ball): if %Ball.position.y < $FlipperRight.get_lowest_point().y: %Ball.apply_central_impulse( Vector2(-abs(%Ball.global_position.x - $FlipperRight.get_center().x), 1.0) * flipper_launch_speed ) if Input.is_action_just_pressed("shake"): %Ball.apply_central_impulse(Vector2(randf_range(-1.5, 1.5), randf_range(-1.5, -0.5))) shake_tween.stop() shake_tween = get_tree().create_tween() var shake_direction = Vector2(randf_range(-1.0, 1.0), randf_range(-1.0, 1.0)) shake_tween.tween_property($Camera2D, "position", camera_base_position + shake_direction, 0.05) shake_tween.tween_property($Camera2D, "position", camera_base_position, 0.05) # fail-safe for non-launched ball. TODO: use different action # TODO: make ball launch manual in general if $LaunchArea.get_overlapping_bodies().has(%Ball): launch_ball() if %Ball.position.y > get_viewport_rect().size.y: $Camera2D.position.y = get_viewport_rect().size.y + get_viewport_rect().size.y / 2.0 camera_base_position.y = $Camera2D.position.y else: $Camera2D.position.y = get_viewport_rect().size.y / 2.0 camera_base_position.y = $Camera2D.position.y func launch_ball() -> void: $Wall.visible = false $Wall.process_mode = Node.PROCESS_MODE_DISABLED var tween := get_tree().create_tween() tween.tween_property(%Ball, "position:y", %Ball.position.y + 5, 0.5) await tween.finished %Ball.apply_central_impulse(Vector2(0, launch_speed)) func _on_outside_body_entered(_body: Node2D) -> void: %Ball.move_body($LaunchArea.global_position) await get_tree().create_timer(0.5).timeout launch_ball() func _on_wall_area_body_exited(_body: Node2D) -> void: $Wall.visible = true $Wall.process_mode = Node.PROCESS_MODE_INHERIT