diff --git a/Game/scripts/ship.gd b/Game/scripts/ship.gd index 0539dbb..6d190b5 100644 --- a/Game/scripts/ship.gd +++ b/Game/scripts/ship.gd @@ -1,12 +1,23 @@ class_name Ship extends RigidBody3D -var speed = 10.0 +@export_group("Movement") +var max_speed = 15.0 +var acceleration = 50.0 +var air_resistance = 0.98 +var turn_speed = 2.0 + +@export_group("Camera") +var camera_distance = 8.0 +var camera_height = 4.0 +var camera_smoothing = 10.0 @onready var camera : Camera3D = get_node("Camera3D") @onready var ball = get_parent().get_node("Ball") @onready var timer_label = get_node("HUD/Control/TimerLabel") +var ball_cam_enabled = true + func _ready(): var game_scene = get_parent() if game_scene and game_scene.has_signal("timer_updated"): @@ -15,73 +26,113 @@ func _ready(): else: print("Game scene not found or doesn't have timer_updated signal") +func _input(event): + if event.is_action_pressed("ui_accept"): # Enter key + ball_cam_enabled = !ball_cam_enabled + func _on_timer_updated(minutes: int, seconds: int): timer_label.text = "%02d:%02d" % [minutes, seconds] -func _physics_process(_delta): - if ball and camera: - # Adjust the offset based on your scene scale - # Increasing Y component to raise the camera higher above the vehicle - var offset = Vector3(0, 2, -2) # Adjust Y to change height - - # Position the camera behind and above the vehicle - var behind_vehicle = global_transform.origin - global_transform.basis.z * offset.z - behind_vehicle += global_transform.basis.y * offset.y - - camera.global_transform.origin = behind_vehicle - camera.look_at(ball.global_transform.origin, Vector3.UP) - -func _integrate_forces(state): - # input_vector represents the movement input relative to the vehicle - var input_vector = get_input_vector() - - # Scale the input_vector by speed - input_vector = input_vector.normalized() * speed - - # Set the linear velocity based on the input - state.linear_velocity = input_vector - - # Rotate the ship to face the movement direction - if input_vector.length() > 0.1: # Only rotate if there's significant movement - var target_direction = input_vector.normalized() - # Create a transform that looks in the target direction - var look_transform = Transform3D() - look_transform.origin = global_transform.origin - look_transform = look_transform.looking_at(global_transform.origin + target_direction, Vector3.UP) - - # Apply the rotation to the ship - state.transform.basis = look_transform.basis - -func get_input_vector() -> Vector3: - var input_vector = Vector3.ZERO - +func _physics_process(delta): if camera: - var camera_transform = camera.global_transform - var forward_direction = -camera_transform.basis.z - var right_direction = camera_transform.basis.x - var y_movement = input_vector.y + _update_camera(delta) - if Input.is_action_pressed("move_forward"): - input_vector += forward_direction - if Input.is_action_pressed("move_backward"): - input_vector -= forward_direction - if Input.is_action_pressed("move_left"): - input_vector -= right_direction - if Input.is_action_pressed("move_right"): - input_vector += right_direction - - # Zero out the Y component to restrict movement to the XZ plane - input_vector.y = 0 - - # Add back the preserved Y movement - input_vector.y = y_movement - - if Input.is_action_pressed("move_up"): - input_vector.y += 1 - if Input.is_action_pressed("move_down"): - input_vector.y -= 1 - - return input_vector.normalized() +func _update_camera(delta): + if ball_cam_enabled and ball: + _update_ball_cam(delta) else: - print("Camera not found") - return Vector3.ZERO + _update_ship_cam(delta) + +func _update_ball_cam(delta): + # In ball cam, camera positions itself so the ship is between camera and ball + var ship_pos = global_transform.origin + var ball_pos = ball.global_transform.origin + + # Calculate direction from ball to ship + var ball_to_ship = (ship_pos - ball_pos).normalized() + + # Position camera behind the ship relative to the ball's position + # This ensures the ship is always between the camera and ball + var camera_target_pos = ship_pos + ball_to_ship * camera_distance + Vector3.UP * camera_height + + # Smoothly move camera to target position + camera.global_transform.origin = camera.global_transform.origin.lerp(camera_target_pos, camera_smoothing * delta) + + # Make camera look at the ball + if camera.global_transform.origin.distance_to(ball_pos) > 0.1: + # Calculate direction to ball + var camera_pos = camera.global_transform.origin + var to_ball = (ball_pos - camera_pos).normalized() + + # Create look-at transform manually + var camera_transform = Transform3D() + camera_transform.origin = camera_pos + camera_transform.basis = Basis.looking_at(to_ball, Vector3.UP) + + # Apply the rotation smoothly + camera.global_transform.basis = camera.global_transform.basis.slerp(camera_transform.basis, camera_smoothing * delta) + +func _update_ship_cam(delta): + # In ship cam, camera follows and looks in the same direction as the ship + var ship_pos = global_transform.origin + var ship_forward = -global_transform.basis.z + + # Position camera behind and above the ship + var camera_target_pos = ship_pos - ship_forward * camera_distance + Vector3.UP * camera_height + + # Smoothly move camera + camera.global_transform.origin = camera.global_transform.origin.lerp(camera_target_pos, camera_smoothing * delta) + + # Make camera look in the same direction as the ship + var look_target = ship_pos + ship_forward * 10.0 # Look ahead of the ship + camera.look_at(look_target, Vector3.UP) + +func _integrate_forces(state): + # Get input in ship's local coordinate system + var input = get_ship_input() + + # Apply forces based on ship's orientation + if input.length() > 0.01: + var ship_forward = -global_transform.basis.z + var ship_right = global_transform.basis.x + + # Calculate movement direction based on ship orientation + var movement_dir = Vector3.ZERO + movement_dir += ship_forward * input.z # Forward/backward + movement_dir += ship_right * input.x # Left/right + movement_dir.y += input.y # Up/down + + # Apply acceleration force + var target_velocity = movement_dir.normalized() * max_speed + var velocity_diff = target_velocity - state.linear_velocity + var force = velocity_diff * acceleration * mass + + state.apply_central_force(force) + + # Turn the ship to face movement direction (only if moving horizontally) + var horizontal_movement = Vector3(movement_dir.x, 0, movement_dir.z) + if horizontal_movement.length() > 0.1: + var target_transform = global_transform.looking_at(global_transform.origin + horizontal_movement, Vector3.UP) + state.transform.basis = state.transform.basis.slerp(target_transform.basis, turn_speed * state.step) + + # Apply air resistance + state.linear_velocity *= air_resistance + +func get_ship_input() -> Vector3: + var input = Vector3.ZERO + + # Get input as if controlling a ship (forward/backward/left/right relative to ship) + if Input.is_action_pressed("move_forward"): + input.z += 1.0 + if Input.is_action_pressed("move_backward"): + input.z -= 1.0 + if Input.is_action_pressed("move_left"): + input.x -= 1.0 + if Input.is_action_pressed("move_right"): + input.x += 1.0 + if Input.is_action_pressed("move_up"): + input.y += 1.0 + if Input.is_action_pressed("move_down"): + input.y -= 1.0 + + return input