Files
Trinittu/scripts/train.gd
2026-01-22 12:09:46 +01:00

190 lines
4.9 KiB
GDScript

extends Node3D
class_name Train
signal speed_changed(new_speed: float)
@export_group("Train")
@export var base_speed: float = 15.0
@export var max_speed: float = 50.0
@export var min_speed: float = 3.0
@export var acceleration: float = 12.0
@export var wagon_spacing: float = 5.5
var num_wagons: int
var group_name: String = ""
var locomotive_model_resources: Array[String] = [
"train-diesel-a.obj",
"train-diesel-b.obj",
"train-diesel-box-a.obj",
"train-diesel-c.obj"
]
var wagon_model_resources: Array[String] = [
"train-carriage-container-blue.obj",
"train-carriage-flatbed-wood.obj",
"train-carriage-lumber.obj",
"train-carriage-tank-large.obj",
"train-diesel-box-b.obj",
"train-diesel-box-c.obj"
]
# Riferimento al generatore (settato da main.gd)
var track_generator: TrackGenerator
# Stato
var current_speed: float = 15.0
var distance_traveled: float = 0.0
var locomotive: Node3D
var wagons: Array = []
var wagon_distances: Array = []
func _ready() -> void:
# Aspetta un frame per assicurarsi che track_generator sia settato
await get_tree().process_frame
await get_tree().process_frame
_create_train()
current_speed = base_speed
func _remove_train():
for node in get_tree().get_nodes_in_group(group_name):
node.queue_free()
func _create_train() -> void:
_remove_train()
_create_locomotive()
wagons = []
wagon_distances = []
num_wagons = randi_range(1, 10)
_create_wagons()
func _create_locomotive() -> void:
var locomotive_model = locomotive_model_resources.pick_random()
locomotive = load_model("res://resources/train kit/" + locomotive_model, "Locomotive")
locomotive.transform.rotated(Vector3(1, 0, 0), 180.0)
group_name = "locomotive" + str(Time.get_unix_time_from_system())
locomotive.add_to_group(group_name)
add_child(locomotive)
func _create_wagons() -> void:
var loco_length = 0
for child in locomotive.get_children():
if child is MeshInstance3D:
var aabb = child.get_aabb()
loco_length = aabb.size.z
for i in range(num_wagons):
var wagon_model = wagon_model_resources.pick_random()
var wagon = load_model("res://resources/train kit/" + wagon_model, "Wagon_%d" % i)
wagon.transform.rotated(Vector3(1, 0, 0), 180.0)
wagon.add_to_group(group_name)
add_child(wagon)
wagons.append(wagon)
wagon_distances.append(loco_length if num_wagons == 1 else 0 * 0.5 + (i + 1) * wagon_spacing)
_position_wagons_initial()
func _position_wagons_initial() -> void:
# Posiziona i vagoni sul tracciato all'avvio
if not track_generator:
return
for i in range(wagons.size()):
var wagon_dist = distance_traveled - wagon_distances[i]
# All'inizio i vagoni potrebbero essere "prima" della partenza
# quindi li posizioniamo dove possibile
if wagon_dist < 0:
wagon_dist = 0
var wagon_data = track_generator.get_position_on_track(wagon_dist)
if wagon_data["valid"]:
_apply_transform(wagons[i], wagon_data["position"], wagon_data["direction"])
func load_model(path: String, node_name: String) -> Node3D:
var mesh = OBJLoader.load_obj(path)
if mesh == null:
return null
# Crea un nodo contenitore
var newobj = Node3D.new()
newobj.name = node_name
# Crea il mesh instance come figlio
var mesh_instance = MeshInstance3D.new()
mesh_instance.mesh = mesh
newobj.add_child(mesh_instance)
return newobj
func _process(delta: float) -> void:
if not track_generator or not locomotive:
return
_handle_input(delta)
_update_movement(delta)
_update_track()
func _handle_input(delta: float) -> void:
if Input.is_action_pressed("speed_up"):
current_speed = min(current_speed + acceleration * delta, max_speed)
speed_changed.emit(current_speed)
elif Input.is_action_pressed("speed_down"):
current_speed = max(current_speed - acceleration * delta, min_speed)
speed_changed.emit(current_speed)
elif Input.is_action_pressed("change_train"):
_create_train()
current_speed = base_speed
func _update_movement(delta: float) -> void:
distance_traveled += current_speed * delta
# Locomotiva
var loco_data = track_generator.get_position_on_track(distance_traveled)
if loco_data["valid"]:
_apply_transform(locomotive, loco_data["position"], loco_data["direction"])
# Vagoni
for i in range(wagons.size()):
var wagon_dist = distance_traveled - wagon_distances[i]
if wagon_dist < 0:
wagon_dist = 0
var wagon_data = track_generator.get_position_on_track(wagon_dist)
if wagon_data["valid"]:
_apply_transform(wagons[i], wagon_data["position"], wagon_data["direction"])
func _apply_transform(node: Node3D, pos: Vector3, direction: Vector3) -> void:
node.global_position = pos
if direction.length_squared() > 0.001:
var target = pos - direction
var up = Vector3.UP
if abs(direction.dot(up)) > 0.99:
up = Vector3.RIGHT
node.look_at(target, up)
func _update_track() -> void:
track_generator.update_track(distance_traveled)
func get_locomotive_position() -> Vector3:
if locomotive:
return locomotive.global_position
return Vector3.ZERO
func get_speed() -> float:
return current_speed