Một đối thủ trên vạch xuất phát
Bài học 13 trên 20 trong khóa học Trò chơi Godot: Mạch neon của Coddy.
Một chiếc xe màu hồng đang chờ bên cạnh bạn. Đó là đối thủ và không cần đánh lái: xe chạy theo đường tâm của đường đua, lệch sang một bên một chút.
Lưu quãng đường xe đã đi quanh đường đua trong progress và tăng giá trị này với tốc độ tối đa của xe. track.point_at(progress) là điểm trên đường tâm đó, còn direction_at là hướng đường đua chạy qua điểm đó:
func place() -> void:
var direction: Vector2 = track.direction_at(progress)
position = track.point_at(progress) + direction.orthogonal() * lane
rotation = direction.angle()lane dịch xe khỏi đường tâm một khoảng tính bằng pixel, nhờ vậy các đối thủ có thể chạy song song. progress tiếp tục tăng sau mỗi vòng đua; point_at đưa giá trị này quay vòng.
Thử thách
DễThêm một chiếc xe đối thủ.
- Trong
rival.gd, khai báo xuấttop_speed := 200.0,lane := 0.0vàstart_offset := 40.0. - Thêm
var progress := 0.0,var active := truevà dòng theo dõi@onready. - Trong
_ready, đặtprogress = start_offsetrồi gọiplace(). - Trong
_physics_process, khi xe đang hoạt động, cộngtop_speed * deltavàoprogressrồi gọiplace().
Nhấn Chơi: chiếc xe màu hồng chạy vòng quanh đường đua. 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