You built a car in Part 1 — now let's make a real race! Build a loop track, count laps with checkpoints, give your car health, make it explode, and add an AI opponent to race against! 🏆
Replace your straight road with a rectangular circuit so you can drive in endless loops!
#444444). Set size to x: 1000, y: 150. Position it at the top of the screen — this is your first straight!Create a checkpoint scene that detects when the car passes through — so laps only count if you drive the whole circuit in order!
@export var id line makes the id field appear in the Godot Inspector — a really handy Godot feature! Make sure the ids are assigned in driving order (clockwise or anti-clockwise) so the lap validation works correctly in the next step.Update our track script to count laps when the car passes all checkpoints in the correct order. After 3 laps — you win!
Lap: 1 / 3.expected_checkpoint — a counter that only advances when the checkpoints are hit in sequence. Hitting them out of order does nothing!Press Play and drive the full circuit. Does the Lap counter go up? Now try driving backwards — the lap should NOT count. Then try to complete 3 full laps to see the win screen!
Add a health system to the car. As health drops, the car slows down — driving badly has consequences!
var speed and var turn_speed lines at the top of your car.gd with these four new variables:In your movement code, change the line that sets velocity so it uses max_speed instead of the old hardcoded value:
is_alive flag will prevent the car from moving after an explosion.Add a take_damage() function that reduces health and slows the car — and when health hits zero, the car explodes with a particle effect!
Add this function to the bottom of car.gd:
if not is_alive: return as the very first line of your _physics_process function — this stops the car moving after it explodes!400 * (health / 100.0) calculates speed as a percentage of max health. At 100 health you get full speed (400), at 50 health you get 200 — a natural feel without lots of extra maths. Note we use 100.0 not 100 to force floating-point division in GDScript.Update _physics_process so hitting a wall at high speed deals real damage — gentle taps are fine, big crashes hurt!
Here is the complete updated _physics_process function. The new part starts after move_and_slide():
In track.gd, add a line to the _process function to keep the HUD health bar updated:
get_slide_collision_count() is Godot's built-in way to check if move_and_slide() hit anything this frame. velocity.length() gives us the speed as a single number (the magnitude of the velocity vector). This is a clean, game-dev-standard approach!Create a glowing green repair pickup. When the car drives over it, health is restored and the pickup disappears!
#06d6a0). Glowing!queue_free() is Godot's safe way to delete a node mid-frame — it queues it for removal at the end of the frame rather than deleting it immediately, which prevents crashes. It's used for anything that should disappear: bullets, pickups, explosions.Crash into walls on purpose to lower your health, then drive over a green pickup. Does the health bar go back up? You should also feel the car speed up again!
Create a red AI car that drives forward and bounces off walls like a pinball. Drop it on the track and race against it!
speed variable to make it faster or slower. Add two AI cars in different positions for extra mayhem! You can also rotate them to face different directions at the start.Change var speed = 250 to 350. Add two AI cars on opposite sides of the track!
Set speed = 150. Or remove the AI car damage from the player (only walls deal damage).
🛠️ Free In-House Dev Tools
Use these free browser tools alongside this workshop to create custom sprites, sounds, and colour schemes for your game. No installs. Free forever.