Files
FFCardGame/scripts/visual/TableCamera.gd

75 lines
2.2 KiB
GDScript

class_name TableCamera
extends Camera3D
## TableCamera - Isometric camera for the game table
# Camera settings
@export var camera_distance: float = 17.0
@export var camera_angle: float = 55.0 # Degrees from horizontal (higher = more top-down)
@export var camera_height_offset: float = -4.0 # Offset to look slightly above center
# Smooth movement
@export var smooth_speed: float = 3.0
var target_position: Vector3 = Vector3.ZERO
var target_look_at: Vector3 = Vector3.ZERO
var is_animating: bool = false
# Current player side (0 = positive Z, 1 = negative Z)
var current_player: int = 0
func _ready() -> void:
_setup_for_player(0, false)
func _setup_for_player(player_index: int, animate: bool = true) -> void:
# Set perspective projection
projection = PROJECTION_PERSPECTIVE
fov = 50.0
current_player = player_index
var angle_rad = deg_to_rad(camera_angle)
var height = camera_distance * sin(angle_rad)
var z_offset = camera_distance * cos(angle_rad)
# Flip Z direction based on player
var side = 1 if player_index == 0 else -1
var new_position = Vector3(0, height, z_offset * side)
target_look_at = Vector3(0, camera_height_offset, 0)
if animate:
target_position = new_position
is_animating = true
else:
position = new_position
target_position = new_position
look_at(target_look_at, Vector3.UP)
is_animating = false
func _process(delta: float) -> void:
if is_animating:
position = position.lerp(target_position, smooth_speed * delta)
look_at(target_look_at, Vector3.UP)
if position.distance_to(target_position) < 0.05:
position = target_position
look_at(target_look_at, Vector3.UP)
is_animating = false
## Switch camera to view from a player's perspective
func switch_to_player(player_index: int) -> void:
if player_index != current_player:
_setup_for_player(player_index, true)
## Set camera to look at a specific point
func focus_on(point: Vector3) -> void:
var angle_rad = deg_to_rad(camera_angle)
var side = 1 if current_player == 0 else -1
target_position = point + Vector3(0, camera_distance * sin(angle_rad),
camera_distance * cos(angle_rad) * side)
is_animating = true
## Reset to default position
func reset_position() -> void:
_setup_for_player(current_player, false)