Độ bám và trượt
Bài học 4 trên 20 trong khóa học Trò chơi Godot: Mạch neon của Coddy.
Đánh lái gấp khiến xe trượt như quả bóng khúc côn cầu: đầu xe hướng về một phía nhưng xe lại di chuyển theo hướng khác. Lốp xe ngăn điều đó. Lốp giúp xe lăn về phía trước nhưng không trượt ngang.
forward.orthogonal() chỉ về phía bên hông xe. Tách vận tốc thành phần theo hướng đó rồi loại bỏ phần lớn thành phần ấy ở mỗi khung hình:
var side := forward.orthogonal()
velocity -= side * velocity.dot(side) * minf(1.0, grip * delta)Khi grip ở mức 7, xe sẽ hướng theo mũi xe một lúc sau khi vào cua, tạo ra cú trượt ngắn. Độ bám càng thấp, cú trượt càng dài. minf(1.0, ...) đảm bảo mỗi khung hình không loại bỏ nhiều hơn toàn bộ thành phần trượt ngang.
Thử thách
DễTăng độ bám của lốp để xe không còn trượt ngang.
- Thêm
@export var grip := 7.0. - Sau đoạn rẽ, thêm hai dòng
sideở trên. - Để thấy xe trượt dài, đổi
gripthành2.0trongcar.gdrồi nhấn Chơi; đặt lại thành7.0trước khi nhấn Kiểm tra.
Nhấn Chơi rồi vào cua: sau một cú trượt ngắn, xe sẽ đi theo hướng đầu xe. 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
var velocity := Vector2.ZERO
func _physics_process(delta: float) -> void:
var throttle := Input.get_axis("move_down", "move_up")
var steer := Input.get_axis("move_left", "move_right")
var forward := Vector2.RIGHT.rotated(rotation)
var speed := velocity.dot(forward)
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)
velocity *= 1.0 - drag * delta
velocity = velocity.limit_length(max_speed)
position += velocity * delta
$Exhaust.emitting = throttle > 0.0
Tất cả bài học trong Trò chơi Godot: Mạch neon
Tự luyện tập: Playground Godot