โš™๏ธ My First C++ Game ยท Episode 7 of 7 ยท See All Episodes
โš”๏ธ Episode 7 ยท Series Finale ยท Tower Defence Part 2 of 2

Wave After Wave!
Tower Defence Part 2

The grand finale: towers open fire with homing bullets, enemies arrive in escalating waves, kills pay bounties, towers upgrade, and a boss leads the final assault. Ship your biggest C++ project.

๐Ÿ‘ถ Ages 12+ โฑ๏ธ ~2 Hours โš™๏ธ C++ & SFML โœ“ Free
๐Ÿ”ซ Firing & cooldowns ๐ŸŽฏ Homing bullets ๐ŸŒŠ Wave system ๐Ÿ’€ Bounties โฌ†๏ธ Upgrades ๐Ÿ‰ Boss wave
โญ
0 XP
Level 1
๐Ÿ”ฅ0
Your Progress 0 / 6 steps
1
๐Ÿ”ซ
Towers Open Fire
Cooldown timers plus your nearestInRange from Part 1
Active
๐ŸŽฏ
Goal for this step

Make towers spawn bullets at the nearest target on a cooldown.

  • 1Continue in your Part 1 project, every system plugs in.
  • 2Bullet struct: position, target enemy index/pointer, speed 340, damage copied from the tower.
  • 3Each tower: cooldown โˆ’= dt; at โ‰ค 0 with a target from nearestInRange โ†’ push a bullet, reset cooldown to 0.7 s.
  • 4Draw bullets as small yellow circles.
tower.cpp
struct Bullet {
    sf::Vector2f pos;
    Enemy* target;
    float speed = 340;
    int damage;
};

std::vector<Bullet> bullets;

for (auto& t : towers) {
    t.cooldown -= dt;
    if (t.cooldown <= 0) {
        Enemy* target = nearestInRange(t, enemies);
        if (target) {
            bullets.push_back({ t.pos, target, 340, t.damage });
            t.cooldown = 0.7f;
        }
    }
}
โœ๏ธ
Fill in the Blanks
+15 XP
A tower may fire when its reaches zero AND nearestInRange returns a target instead of . Firing resets the cooldown to 0.7 s.
๐Ÿง 
Knowledge Check
+15 XP
Why does the cooldown only reset when a shot is actually fired?
ATo save memory
BSo a tower with no targets fires the INSTANT one appears, rather than being mid-cooldown for nothing
CCooldowns cannot reset twice
2
๐ŸŽฏ
Homing Bullets
Chase the target using Part 1 vector maths
Locked
๐ŸŽฏ
Goal for this step

Bullets home in, hit, damage, and clean themselves up.

  • 1Bullet update = enemy path-following aimed at a moving point: normalise (target โˆ’ pos), move by speedยทdt.
  • 2Within 8 px: apply damage, mark the bullet dead. Dead or escaped target? Kill the bullet too (its pointer is stale!).
  • 3Enemy hp โ‰ค 0 โ†’ alive = false and pay the bounty: gold += e.bounty;
  • 4Clean dead bullets with erase-remove (Episode 3-4 skill). Fire away!
tower.cpp
for (auto& b : bullets) {
    if (!b.target->alive) { b.dead = true; continue; }
    sf::Vector2f d = b.target->pos - b.pos;
    float len = std::sqrt(d.x*d.x + d.y*d.y);
    if (len < 8.f) {
        b.target->hp -= b.damage;
        if (b.target->hp <= 0) {
            b.target->alive = false;
            gold += b.target->bounty;
        }
        b.dead = true;
    } else {
        b.pos += (d / len) * b.speed * dt;
    }
}
bullets.erase(std::remove_if(bullets.begin(), bullets.end(),
    [](const Bullet& b){ return b.dead; }), bullets.end());
โŒจ๏ธ
Code Challenge
+20 XP
Pay the bounty on a kill:
tower.cpp
b.target->hp -= b.;
if (b.target->hp <= ) {
    b.target->alive = false;
    gold += b.target->;
}
๐Ÿ’ก Hint: The bullet carries its damage; death is zero-or-less hp; the kill reward was staged in Part 1.
๐Ÿง 
Knowledge Check
+15 XP
Why must a bullet die when its target dies?
ABullets are expensive
BIts target pointer now refers to a dead enemy, chasing it is meaningless and using it after removal is dangerous
CSFML limits bullets
3
๐ŸŒŠ
The Wave System
Timed spawning of escalating enemy groups
Locked
๐ŸŽฏ
Goal for this step

Spawn enemies in numbered waves with growing difficulty.

  • 1Wave state: number, enemies left to spawn, a spawn-gap timer (0.8 s), and a between-waves rest (5 s).
  • 2Wave n: 4 + n*2 enemies, hp 20 + n*8, speed 70 + n*4.
  • 3All spawned AND all dead/escaped โ†’ rest timer โ†’ next wave.
  • 4HUD: "Wave 3, 6 enemies remain" and "Next wave in 3โ€ฆ" during rests. Information is a tower defence playerโ€™s oxygen.
tower.cpp
int wave = 0, toSpawn = 0;
float spawnGap = 0, rest = 3;

if (toSpawn == 0 && enemiesCleared(enemies)) {
    rest -= dt;
    if (rest <= 0) {
        wave++;
        toSpawn = 4 + wave * 2;
        rest = 5;
    }
} else if (toSpawn > 0) {
    spawnGap -= dt;
    if (spawnGap <= 0) {
        Enemy e;
        e.pos = path[0];
        e.hp = 20 + wave * 8;
        e.speed = 70 + wave * 4;
        enemies.push_back(e);
        toSpawn--;
        spawnGap = 0.8f;
    }
}
โœ๏ธ
Fill in the Blanks
+15 XP
Wave n spawns 4 + nร— enemies with a second gap between them, followed by a second rest before the next wave.
๐Ÿง 
Knowledge Check
+15 XP
The rest period between waves exists so players canโ€ฆ
AGet snacks
BSpend their bounty gold, build and upgrade between assaults. Tension, release, decision. That is the TD loop
CLet the CPU cool down
4
โฌ†๏ธ
Tower Upgrades
Right-click to upgrade: damage, range, fire rate
Locked
๐ŸŽฏ
Goal for this step

Add a 3-level upgrade path that changes the maths meaningfully.

  • 1Tower gains int level = 1. Right-clicking one (mouse within 20 px of its centre) upgrades if gold allows.
  • 2Cost 40ร—level. Effects per level: damage +4, range +25, cooldown ร—0.8.
  • 3Show level as small pips on the tower; deepen its colour per level.
  • 4Strategy emerges: three level-1 towers or one level-3? (Spoiler: focused fire usually wins, let players discover it.)
tower.cpp
// on right-click near tower t:
int cost = 40 * t.level;
if (gold >= cost && t.level < 3) {
    gold -= cost;
    t.level++;
    t.damage += 4;
    t.range  += 25;
    t.fireTime *= 0.8f;    // faster firing
}
โŒจ๏ธ
Code Challenge
+20 XP
Apply the level-up bonuses:
tower.cpp
t.level++;
t.damage += ;
t.range  += ;
t.fireTime *= f;
๐Ÿ’ก Hint: Damage grows by four, range by twenty-five, and the time between shots shrinks to 80%.
๐Ÿง 
Knowledge Check
+15 XP
Multiplying fireTime by 0.8 per level (instead of subtracting) meansโ€ฆ
AUpgrades get weaker
BCompounding: 0.7s โ†’ 0.56s โ†’ 0.45s, each level stays a meaningful % boost without ever hitting zero
CThe tower jams
5
๐Ÿ‰
The Boss Wave
Wave 10: a tank with a health bar leads the charge
Locked
๐ŸŽฏ
Goal for this step

Cap the game with a boss that tests the playerโ€™s whole build.

  • 1Wave 10 spawns one BOSS: hp 600, speed 40, bounty 200, drawn twice the size with a floating health bar.
  • 2A boss health bar: red back-bar + green front scaled by hp/maxHp, hovering above it (you have built this bar in two languages!).
  • 3Boss escapes โ†’ instant defeat (lives = 0). Boss dies โ†’ VICTORY screen.
  • 4A slow tank rewards sustained damage, upgraded tower clusters shine, exactly what the player has been learning to build.
tower.cpp
if (wave == 10 && toSpawn == 1) {     // last spawn = the boss
    Enemy boss;
    boss.pos = path[0];
    boss.hp = 600;  boss.maxHp = 600;
    boss.speed = 40;
    boss.bounty = 200;
    boss.isBoss = true;
    enemies.push_back(boss);
    toSpawn = 0;
}

// boss escape = instant loss:
if (e.isBoss && e.wp >= (int)path.size())
    lives = 0;
โœ๏ธ
Fill in the Blanks
+15 XP
The boss has hp but only speed 40, a slow . If it escapes, lives drops instantly to .
๐Ÿง 
Knowledge Check
+15 XP
A good final boss testsโ€ฆ
AReaction speed only
BEverything the game taught: economy, placement, upgrades, a slow tank is an exam on total damage output
CThe pause button
6
๐Ÿ†
Victory, Defeat & Series Wrap
End screens, restart, and your C++ journey reviewed
Locked
๐ŸŽฏ
Goal for this step

Finish the game and take stock of a serious achievement.

  • 1DEFEAT at lives โ‰ค 0; VICTORY when the boss dies. Both freeze play, show wave reached + towers built, R restarts fresh.
  • 2What you used across 7 episodes: compilation & linking, dt physics, structs/classes/enums, deque/vector, pointers & nullptr, normalised vectors, erase-remove, cooldown systems, state machines.
  • 3That list IS an engine-programming foundation. Unreal C++ will read like your own code.
  • 4Series complete. Take the quiz, claim the badge, and go build something nobody has seen before. โš™๏ธ๐ŸŽ‰
๐Ÿ’ก
Want to keep going in C++? Add tower types (slow/splash), a second map, or save the best wave to a file. Every one is within your reach now.
โœ๏ธ
Fill in the Blanks
+15 XP
Across the series you used std::deque for , normalised vectors for following, and nullptr-returning searches for tower .
๐Ÿง 
Knowledge Check
+15 XP
The single most C++-specific superpower you practised in this series isโ€ฆ
ADrawing rectangles
BChoosing precise tools, structs vs classes, deque vs vector, pointers, enums, control over exactly how data lives
CUsing the mouse
๐ŸŽ‰๐Ÿ†๐ŸŽฎโœจ๐ŸŽ‰
Workshop Complete!
Seven episodes of C++: Pong to a full tower defence with waves, upgrades and a boss. You are a C++ game programmer now. Go build YOUR game. โš™๏ธ๐Ÿ†
0
Total XP
1
Level
0
Best Streak
0%
Accuracy
โญ View My Progress & Certificates

This workshop was free and took many hours to build. If it helped you learn something new, consider supporting the project.

☕ Support on Ko-fi