<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Dojo Defender: Session 6 :: CoderDojo Python &amp; Pygame</title><link>https://python.coderdojohasselt.be/en/dojo-defender/session-6/index.html</link><description>Today you add a final boss to Dojo Defender. The boss appears every 5 waves and has 3 phases with their own behaviour. You learn to work with a state machine of its own, HP bars and screen effects.
What you’ll learn today State machine for a boss: PHASE_1, PHASE_2, PHASE_3 and EXPLODING Drawing an HP bar with a colour gradient (green → yellow → red) Homing bullets: a bullet that moves towards the player Screen shake: a random offset on the drawing coordinates Phase transitions with visual effects Step 0: Download the starter The starter is the solution of session 5 — Dojo Defender with parallax stars, particles and splitting asteroids.</description><generator>Hugo</generator><language>en</language><atom:link href="https://python.coderdojohasselt.be/en/dojo-defender/session-6/index.xml" rel="self" type="application/rss+xml"/><item><title>Dojo Defender Session 6: Cheatsheet</title><link>https://python.coderdojohasselt.be/en/dojo-defender/session-6/cheatsheet/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://python.coderdojohasselt.be/en/dojo-defender/session-6/cheatsheet/index.html</guid><description>Starting the boss def start_boss(): global boss_active, boss, boss_hp, boss_phase boss_active = True boss = GameObject('boss.png', WIDTH / 2, -80) boss_hp = 50 boss_phase = "PHASE_1" ... def check_boss_wave(): if wave >= 5 and wave % 5 == 0 and not boss_active: start_boss() Boss AI — state machine if boss.rect.centery &lt; 80: boss.rect.centery += 2 else: if boss_phase == "PHASE_1": # Drift slowly, now and then a bullet boss.rect.centerx += boss_direction * 1.5 if boss_shoot_timer >= 60: fire_boss_bullet() elif boss_phase == "PHASE_2": # Faster + minions boss.rect.centerx += boss_direction * 3 if boss_shoot_timer >= 40: fire_boss_bullet() if boss_minion_spawn_timer >= 180: spawn_boss_minion() elif boss_phase == "PHASE_3": # Enraged + screen shake boss.rect.centerx += boss_direction * 4 if boss_shoot_timer >= 20: fire_boss_bullet() Phase transition hp_ratio = boss_hp / boss_hp_max if hp_ratio &lt;= 0.66 and boss_phase == "PHASE_1": boss_phase = "PHASE_2" boss_phase_transition_timer = 20 if hp_ratio &lt;= 0.33 and boss_phase == "PHASE_2": boss_phase = "PHASE_3" boss_phase_transition_timer = 20 Last phase check if hp_ratio &lt;= 0.33 and boss_phase == "PHASE_2": boss_phase = "PHASE_3" boss_phase_transition_timer = 20 Homing bullet def fire_boss_bullet(): dx = ship.rect.centerx - boss.rect.centerx dy = ship.rect.centery - boss.rect.centery dist = math.sqrt(dx * dx + dy * dy) if dist == 0: dist = 1 boss_bullets.append({ 'x': boss.rect.centerx, 'y': boss.rect.centery + 30, 'vx': dx / dist * 3, 'vy': dy / dist * 3, }) Screen shake # In update: if boss_phase == "PHASE_3": screen_shake_x = random.randint(-3, 3) screen_shake_y = random.randint(-3, 3) # In draw, add an offset everywhere: draw_stars(screen, screen_shake_x, screen_shake_y) HP bar bar_width, bar_height = 300, 20 bar_x = (WIDTH - bar_width) // 2 bar_y = 10 pygame.draw.rect(screen, (100, 20, 20), (bar_x, bar_y, bar_width, bar_height)) hp_ratio = max(0, boss_hp / boss_hp_max) fill_width = int(bar_width * hp_ratio) color = (0, 255, 0) if hp_ratio > 0.5 else (255, 255, 0) if hp_ratio > 0.25 else (255, 0, 0) pygame.draw.rect(screen, color, (bar_x, bar_y, fill_width, bar_height)) pygame.draw.rect(screen, (255, 255, 255), (bar_x, bar_y, bar_width, bar_height), 2) Boss defeated if boss_hp &lt;= 0: boss_phase = "EXPLODING" boss_defeated_timer = 90 score += 500 if boss_phase == "EXPLODING": if boss_phase_transition_timer % 10 == 0: spawn_particles(...)</description></item><item><title>Dojo Defender Session 6: Coach notes</title><link>https://python.coderdojohasselt.be/en/dojo-defender/session-6/mentor-notes/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://python.coderdojohasselt.be/en/dojo-defender/session-6/mentor-notes/index.html</guid><description>Goal of this session After this session a ninja can:
Build a state machine for a boss (PHASE_1/2/3/EXPLODING) Draw an HP bar with a dynamic fill level and colour Make homing bullets with vector maths (dx / dist * speed) Implement screen shake via a random drawing offset Show phase transitions with visual effects (flashing) Preparation (30 min before the session) Starter ZIPs ready on USB and on the site: dojo-defender-s7-starter.en.zip and dojo-defender-s7-solution.en.zip. Run the starter once on the dojo room laptop. Check whether boss.png and boss_minion.png are in the images/ folder of the starter. Explain the state machine on the board: draw a circle diagram with 4 states (PHASE_1 → PHASE_2 → PHASE_3 → EXPLODING) and arrows between them. Explain the unit vector: “dx / dist” gives a direction with length 1. Handy for bullets in every direction. Schedule (3 hours) This session is an integral part of the normal session 7 (Bug Zapper). Use the time like this:</description></item><item><title>Dojo Defender Session 6: Demo</title><link>https://python.coderdojohasselt.be/en/dojo-defender/session-6/demo/index.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://python.coderdojohasselt.be/en/dojo-defender/session-6/demo/index.html</guid><description>How to demo the solution Open a terminal in the project folder. Run: uv run python3 code/sessions/07-bug-zapper/dojo-defender-solution/main.py Show:
SPACE starts the game, shoot until wave 5 Wave 5: the boss comes in from above HP bar at the top: green → yellow → red as HP drops Phase 1: drifting slowly, now and then a red bullet Phase 2: moving faster, more bullets, minions spawning Phase 3: screen shakes, 2 bullets at once Phase transition: boss flashes white Defeating the boss: big explosion + “BOSS DEFEATED!” + 500 points Ordinary waves continue after the boss Code highlights to show:</description></item></channel></rss>