Menu
CoddyTech

Chậm ở khúc cua

Bài học 14 trên 20 trong khóa học Trò chơi Godot: Mạch neon của Coddy.

Đối thủ lao hết tốc độ qua các khúc cua, điều mà không tài xế nào làm. Hãy để xe giảm tốc khi vào cua. track.turn_ahead(progress, 70.0) cho biết đường cong nhiều đến mức nào trong 70 pixel tiếp theo, tính bằng radian.

Khúc cua càng gắt, tốc độ xe nhắm đến càng thấp, giảm tối đa 18 phần trăm. Sau đó, xe từ từ điều chỉnh đến tốc độ đó, giống như khi xe tăng tốc và giảm tốc:

var turn: float = track.turn_ahead(progress, 70.0)
var target := top_speed * (1.0 - clampf(turn / 3.0, 0.0, 0.18))
speed = move_toward(speed, target, 160.0 * delta)
progress += speed * delta

Giờ đây, đối thủ xuất phát từ trạng thái đứng yên, giống như bạn.

challenge icon

Thử thách

Dễ

Khiến đối thủ giảm tốc trước các khúc cua.

  1. Thêm var speed := 0.0 vào rival.gd.
  2. Thay progress += top_speed * delta bằng bốn dòng ở trên.

Nhấn Chơi: đối thủ tăng tốc từ trạng thái đứng yên và giảm tốc trước mỗi khúc cua. Sau đó, nhấn Kiểm tra.

Tự làm thử

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
var active := true

@onready var track: Node2D = $"../Track"


func _physics_process(delta: float) -> void:
	var throttle := 0.0
	var steer := 0.0
	if active:
		throttle = Input.get_axis("move_down", "move_up")
		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

Tất cả bài học trong Trò chơi Godot: Mạch neon

Tự luyện tập: Playground Godot