Files
train-game/tests/switch_test.gd
2026-09-16 17:55:38 +02:00

176 lines
5.4 KiB
GDScript

extends Node
## Weichen: Route wählen, Übergang ohne Sprung, Bergstrecke erreichbar.
var main
var step := 0
var wait := 0.0
var ok := 0
var fail := 0
var last_pos := Vector3.ZERO
var worst_jump := 0.0
var jump_frames := 0
var _dbg := 0.0
var _cam_hits := 0
var _cam_pulled := 0
var _cam_yaw := 0
func chk(n: String, c: bool, i := "") -> void:
if c: ok += 1; print(" OK %s %s" % [n, i])
else: fail += 1; print(" FAIL %s %s" % [n, i])
func _key(c: int, d: bool) -> void:
var e := InputEventKey.new(); e.physical_keycode = c; e.keycode = c; e.pressed = d
Input.parse_input_event(e)
func _watch(d: float) -> void:
var t = main.train
var p: Vector3 = t.cars[t.cars.size() - 1].global_position
if last_pos != Vector3.ZERO and d > 0.0:
var jump := p.distance_to(last_pos)
var allowed: float = t.speed * d * 1.5 + 0.05
if jump > allowed:
jump_frames += 1
worst_jump = maxf(worst_jump, jump - t.speed * d)
last_pos = p
## Im Physik-Takt messen: dort bewegt sich der Zug genau einmal pro Aufruf.
func _physics_process(d: float) -> void:
if main != null and main.started and step >= 1 and step <= 8:
_watch(d)
func _process(d):
if main == null:
main = get_tree().current_scene
return
if not main.started:
main._start_solo()
return
var t = main.train
if wait > 0.0:
wait -= d
return
match step:
0:
chk("Drei Abschnitte", main.track.segments.size() == 3)
chk("Heimstrecke hat Weiche", main.track.is_switch(2))
chk("Sechs Bahnhöfe", main.stations.size() == 6)
main._park_at(main.stations[4]) # Ahornstadt, Heimstrecke
chk("Start auf Heimstrecke", t.seg == 2, "seg=%d" % t.seg)
chk("Weiche voraus erkannt", t.upcoming_switch() == 2)
var nxt: Array = t.next_station()
chk("Nächster Halt Waldkirch (links)", nxt[0].station_name == "Waldkirch",
"%s" % nxt[0].station_name)
t.switch_choice = 1
var nxt2: Array = t.next_station()
chk("Nächster Halt Bergblick (rechts)", nxt2[0].station_name == "Bergblick",
"%s" % nxt2[0].station_name)
t.switch_choice = 0
main.driver_id = 1
_key(KEY_W, true)
last_pos = Vector3.ZERO
wait = 1.0
1:
wait = 0.5
2:
if t.seg != 0:
step -= 1
wait = 0.3
_dbg += 0.3
if _dbg >= 2.0:
_dbg = 0.0
print("[dbg] seg=%d prog=%.1f/%.1f v=%.1f thr=%.1f driver=%d mode=%d" % [t.seg, t.progress,
main.track.seg_length(t.seg), t.speed, t.throttle, main.driver_id, main.player.mode])
else:
_key(KEY_W, false)
_key(KEY_S, true)
chk("Links -> Talstrecke", t.seg == 0, "seg=%d" % t.seg)
chk("Historie geführt", t.history.size() > 0 and t.history[t.history.size() - 1] == 2,
"%s" % [t.history])
chk("Letzter Wagen ohne Sprung", jump_frames == 0,
"Sprungframes=%d, größter Sprung %.2f m" % [jump_frames, worst_jump])
wait = 4.0
3:
_key(KEY_S, false)
main._park_at(main.stations[4])
t.switch_choice = 1
last_pos = Vector3.ZERO
jump_frames = 0
worst_jump = 0.0
_key(KEY_D, true)
_key(KEY_W, true)
wait = 1.0
4:
wait = 0.5
5:
if t.seg != 1:
step -= 1
wait = 0.3
else:
chk("Rechts -> Bergstrecke", t.seg == 1, "seg=%d" % t.seg)
chk("D hält die Weiche rechts", t.switch_choice == 1)
chk("Übergang rechts ohne Sprung", jump_frames == 0,
"Sprungframes=%d" % jump_frames)
_key(KEY_D, false)
wait = 0.5
6:
var nxt: Array = t.next_station()
chk("Bergblick voraus", nxt[0].station_name == "Bergblick", "%s" % nxt[0].station_name)
wait = 0.5
7:
# bis kurz vor Bergblick fahren, dann bremsen
var berg = main.stations[5]
var ahead: float = t.distance_ahead(berg)
if ahead > t.speed * t.speed / 16.0 + 8.0:
step -= 1
wait = 0.2
else:
_key(KEY_W, false)
_key(KEY_S, true)
wait = 6.0
8:
_key(KEY_S, false)
chk("Zug steht", t.speed < 0.05, "v=%.2f" % t.speed)
chk("Am Bergblick angekommen", t.docked_at != null and t.docked_at.station_name == "Bergblick",
"dock=%s" % ("-" if t.docked_at == null else t.docked_at.station_name))
# Sichtkontrolle: Kreuzung von oben
main._park_at(main.stations[4])
t.place_head(2, main.track.seg_length(2) - 6.0)
main._toggle_camera()
main.cam_rig.distance = 95.0
main.cam_rig.pitch = deg_to_rad(-70.0)
main.cam_rig.yaw = 0.4
wait = 1.0
9:
get_viewport().get_texture().get_image().save_png("user://junction.png")
t.place_head(0, main.track.seg_length(0) - 20.0)
main.cam_rig.snap_to(t.cars[0].global_position)
wait = 1.0
10:
get_viewport().get_texture().get_image().save_png("user://junction2.png")
# Kamera-Kollision: Fokus auf den Bahnsteig, rundherum drehen
var st = main.stations[0]
main.cam_rig.target = null
main.cam_rig.snap_to(st.global_position + Vector3(0, 0, 0))
main.cam_rig.distance = 30.0
main.cam_rig.pitch = deg_to_rad(-10.0)
_cam_hits = 0
_cam_yaw = 0
wait = 0.2
11:
if _cam_yaw < 12:
main.cam_rig.yaw = _cam_yaw * TAU / 12.0
_cam_yaw += 1
step -= 1
wait = 0.15
if main.cam_rig.blocked:
_cam_hits += 1
var dist: float = main.cam_rig._cam.global_position.distance_to(main.cam_rig.global_position)
if dist < 29.0:
_cam_pulled += 1
else:
chk("Kamera stößt am Gebäude an", _cam_hits > 0, "%d von 12 Richtungen" % _cam_hits)
chk("Kamera rückt davor", _cam_pulled == _cam_hits, "%d/%d" % [_cam_pulled, _cam_hits])
12:
print("== %d ok, %d fail ==" % [ok, fail])
get_tree().quit(1 if fail > 0 else 0)
step += 1