Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extends CharacterBody3D
- class_name Player
- # Ссылки на компоненты
- @onready var health_system: HealthSystem = $HealthSystem
- @onready var stamina_system: StaminaSystem = $StaminaSystem
- @onready var movement_system: MovementSystem = $MovementSystem
- @onready var camera_pivot: Node3D = $CameraPivot
- @onready var camera: Camera3D = $CameraPivot/Camera3D
- @onready var mesh: MeshInstance3D = $MeshInstance3D
- # Настройки камеры
- @export var camera_distance: float = 10.0
- @export var camera_height: float = 8.0
- @export var camera_angle: float = -30.0 # Для изометрии
- # Переменные для ввода
- var movement_input: Vector2 = Vector2.ZERO
- var look_direction: Vector2 = Vector2.ZERO
- var mouse_position: Vector2 = Vector2.ZERO
- # Сигналы для других систем
- signal health_changed(new_health: float, max_health: float)
- signal stamina_changed(movement_stamina: float, dash_stamina: float)
- signal player_died
- signal player_damaged(damage: float)
- func _ready():
- # Настройка камеры для изометрической проекции
- setup_camera()
- # Подключение сигналов систем
- health_system.health_changed.connect(_on_health_changed)
- health_system.died.connect(_on_player_died)
- stamina_system.stamina_changed.connect(_on_stamina_changed)
- # Добавление в группу игроков
- add_to_group("player")
- func setup_camera():
- # Камера зафиксирована в изометрической позиции и НЕ поворачивается с персонажем
- camera_pivot.position = Vector3.ZERO
- camera.position = Vector3(0, camera_height, camera_distance)
- camera.rotation_degrees = Vector3(camera_angle, 0, 0)
- camera.projection = Camera3D.PROJECTION_ORTHOGONAL
- camera.size = 20 # Размер ортогональной проекции
- func _input(event):
- # Получение позиции мыши для направления взгляда
- if event is InputEventMouseMotion:
- mouse_position = event.position
- func _process(delta):
- handle_input()
- update_look_direction()
- func _physics_process(delta):
- # Передача ввода в систему движения
- movement_system.process_movement(movement_input, delta)
- # Применение результата движения к CharacterBody3D
- velocity = movement_system.get_velocity()
- move_and_slide()
- func handle_input():
- # Получение ввода движения
- movement_input = Vector2(
- Input.get_axis("move_left", "move_right"),
- Input.get_axis("move_up", "move_down")
- )
- # Проверка действий
- if Input.is_action_just_pressed("jump"):
- movement_system.try_jump()
- if Input.is_action_just_pressed("sprint"):
- movement_system.toggle_sprint()
- if Input.is_action_just_pressed("roll"):
- var roll_direction = movement_input if movement_input.length() > 0 else look_direction
- movement_system.try_roll(roll_direction)
- if Input.is_action_just_pressed("dash"):
- var dash_direction = movement_input if movement_input.length() > 0 else look_direction
- movement_system.try_dash(dash_direction)
- func update_look_direction():
- # Простой расчёт направления взгляда от центра экрана к курсору
- var viewport = get_viewport()
- var screen_center = viewport.get_visible_rect().size / 2
- var mouse_pos = viewport.get_mouse_position()
- # Вычисляем направление от центра к курсору
- var screen_direction = (mouse_pos - screen_center).normalized()
- # Преобразуем в игровое направление (учитывая изометрию)
- look_direction = Vector2(screen_direction.x, -screen_direction.y)
- # Поворачиваем ТОЛЬКО меш персонажа, НЕ камеру и НЕ весь CharacterBody3D
- if look_direction.length() > 0.1:
- var target_rotation = atan2(-look_direction.x, -look_direction.y)
- mesh.rotation.y = lerp_angle(mesh.rotation.y, target_rotation, 8.0 * get_process_delta_time())
- # Методы для получения урона и восстановления
- func take_damage(damage: float, source: Node = null):
- health_system.take_damage(damage)
- player_damaged.emit(damage)
- func heal(amount: float):
- health_system.heal(amount)
- func restore_stamina(amount: float, stamina_type: StaminaSystem.StaminaType):
- stamina_system.restore_stamina(amount, stamina_type)
- # Обработчики сигналов
- func _on_health_changed(new_health: float, max_health: float):
- health_changed.emit(new_health, max_health)
- func _on_player_died():
- # Логика смерти игрока
- movement_system.set_can_move(false)
- player_died.emit()
- func _on_stamina_changed(movement_stamina: float, dash_stamina: float):
- stamina_changed.emit(movement_stamina, dash_stamina)
- # Геттеры для других систем
- func get_health_percentage() -> float:
- return health_system.get_health_percentage()
- func get_stamina_percentage(stamina_type: StaminaSystem.StaminaType) -> float:
- return stamina_system.get_stamina_percentage(stamina_type)
- func is_alive() -> bool:
- return health_system.is_alive()
- func can_sprint() -> bool:
- return stamina_system.can_use_stamina(movement_system.sprint_stamina_cost, StaminaSystem.StaminaType.MOVEMENT)
- func can_roll() -> bool:
- return stamina_system.can_use_stamina(movement_system.roll_stamina_cost, StaminaSystem.StaminaType.MOVEMENT)
- func can_dash() -> bool:
- return stamina_system.can_use_stamina(movement_system.dash_stamina_cost, StaminaSystem.StaminaType.DASH)
Advertisement
Add Comment
Please, Sign In to add comment