Kontrollpunkte der Reihe nach
Lektion 9 von 20 im Kurs Godot-Spiel: Neon-Rennstrecke von Coddy.
Ein Rennen braucht Runden, und eine Runde zählt nur, wenn du wirklich einmal herumgefahren bist. Andernfalls könntest du die Linie überqueren, zurückfahren und sie noch einmal überqueren. Deshalb hat die Strecke 8 gleichmäßig verteilte Kontrollpunkte, die der Reihe nach passiert werden müssen.
Das Rennen befindet sich in race.gd auf dem Main-Knoten. track.offset_of(point) gibt an, wie weit ein Punkt auf der Strecke herum liegt, von 0 an der Linie bis track.length. Kontrollpunkt k liegt bei k * seg:
func check_progress() -> void:
var seg: float = track.length / CHECKPOINTS
var offset: float = track.offset_of(car.position)
var target := next_checkpoint * seg
var gap: float = absf(wrapf(offset - target, -track.length / 2.0, track.length / 2.0))
if gap < 24.0 and track.is_on_road(car.position):
next_checkpoint = (next_checkpoint + 1) % CHECKPOINTSwrapf hält den Abstand an der Linie korrekt, wo 1390 und 5 nur 14 Pixel voneinander entfernt sind. % CHECKPOINTS setzt den nächsten Kontrollpunkt nach Kontrollpunkt 7 auf 0, die Linie. Durch die Abfrage von is_on_road zählt eine Abkürzung über das Gras nie.
Aufgabe
Mittel- Füge in
race.gdconst CHECKPOINTS := 8undvar next_checkpoint := 1hinzu. - Hole dir mit
@onreadytrack($Track) undcar($Car). - Schreibe
check_progressund rufe es von_physics_processaus auf.
Probier es selbst
extends Node2D
@export var accel := 260.0
@export var max_speed := 200.0
@export var turn_speed := 3.2
@export var drag := 0.6
@export var grip := 7.0
var velocity := Vector2.ZERO
var boost_time := 0.0
var boost_charge := 0.0
@onready var track: Node2D = $"../Track"
func _physics_process(delta: float) -> void:
var throttle := Input.get_axis("move_down", "move_up")
var steer := Input.get_axis("move_left", "move_right")
if Input.is_action_just_pressed("action") and boost_charge >= 1.0:
boost_charge = 0.0
boost_time = 1.0
boost_charge = minf(1.0, boost_charge + delta / 10.0)
$"../HUD/Boost".scale.x = boost_charge
var forward := Vector2.RIGHT.rotated(rotation)
var speed := velocity.dot(forward)
var top := max_speed
var grip_now := grip
if boost_time > 0.0:
boost_time -= delta
top = max_speed * 1.3
velocity += forward * accel * delta
for pad in get_tree().get_nodes_in_group("boost_pads"):
if position.distance_to(pad.position) < 22.0:
boost_time = maxf(boost_time, 0.4)
for oil in get_tree().get_nodes_in_group("oil"):
if position.distance_to(oil.position) < 20.0:
grip_now = grip * 0.12
if not track.is_on_road(position):
top = max_speed * 0.45
velocity *= 1.0 - 2.5 * delta
if throttle < 0.0 and speed > 10.0:
velocity += forward * throttle * accel * 1.6 * delta
else:
velocity += forward * throttle * accel * delta
rotation += steer * turn_speed * delta * clampf(absf(speed) / 90.0, 0.0, 1.0) * signf(speed + 0.01)
var side := forward.orthogonal()
velocity -= side * velocity.dot(side) * minf(1.0, grip_now * delta)
velocity *= 1.0 - drag * delta
if velocity.length() > top:
velocity = velocity.move_toward(velocity.limit_length(top), accel * 2.0 * delta)
position += velocity * delta
$Exhaust.emitting = throttle > 0.0 or boost_time > 0.0
$Flame.visible = boost_time > 0.0
Alle Lektionen in Godot-Spiel: Neon-Rennstrecke
Übe selbstständig: Godot-Playground