Skip to content

Creating path-following sprites for tower defense games in Scratch

💡 Struggling with enemy AI and pathfinding systems? Need help with game mechanics? 🚀 Get Expert Help

PM

PathfindingMaster

Posted on January 30, 2024 • Intermediate

🛡️ Need Help with Enemy Pathfinding in Tower Defense

Hey everyone! I’m working on a tower defense game in Scratch and I’m struggling with the enemy movement system. Here’s what I need to achieve:

  • Enemies (“monsters”) should follow a predefined path to reach a castle
  • They need to stop mid-path to fight defenders when necessary
  • Enemies should disappear when they reach the end of the path
  • The path itself should be completely invisible to players

I’ve tried basic movement blocks but can’t figure out how to make them follow a complex path smoothly. Any suggestions for implementing this pathfinding system? 🤔

AI

AIPathfinding_Expert

Replied 2 hours later • ⭐ Best Answer

Great question @PathfindingMaster! Tower defense pathfinding is a classic game development challenge. Here’s a comprehensive solution for your enemy movement system:

🗺️ Pathfinding System Architecture

Here’s how your enemy pathfinding system should work:

flowchart TD A[👹 Enemy Spawns] --> B[Load Waypoint Path] B --> C[Move to Next Waypoint] C --> D{Defender Nearby?} D -->|Yes| E[Stop & Enter Combat] D -->|No| F[Continue Moving] E --> G{Combat Resolved?} G -->|Enemy Wins| F G -->|Enemy Dies| H[💀 Remove Enemy] F --> I{Reached Waypoint?} I -->|No| C I -->|Yes| J{More Waypoints?} J -->|Yes| K[Next Waypoint] J -->|No| L[🏰 Reached Castle] K --> C L --> M[Deal Damage to Castle] M --> N[💨 Enemy Disappears] style A fill:#ffebee style L fill:#e8f5e8 style H fill:#fce4ec style N fill:#e3f2fd

📍 Step 1: Create the Waypoint System

First, set up your invisible waypoint system:

    // Waypoint Manager (invisible sprite)
when flag clicked
// Define your path waypoints (x, y coordinates)
set [waypoint 1 x v] to [-200]
set [waypoint 1 y v] to [100]
set [waypoint 2 x v] to [-100]
set [waypoint 2 y v] to [150]
set [waypoint 3 x v] to [0]
set [waypoint 3 y v] to [100]
set [waypoint 4 x v] to [100]
set [waypoint 4 y v] to [50]
set [waypoint 5 x v] to [200]
set [waypoint 5 y v] to [0]

// Total waypoints in path
set [total waypoints v] to [5]

// Castle position (final destination)
set [castle x v] to [220]
set [castle y v] to [0]

hide // Keep waypoint manager invisible
  

👹 Step 2: Enemy Movement System

Create the main enemy sprite with pathfinding logic:

    // Enemy Sprite
when flag clicked
set [current waypoint v] to [1]
set [enemy speed v] to [3]
set [enemy health v] to [100]
set [in combat v] to [0]
set [combat target v] to []

// Start at spawn position
go to x: [-240] y: [100]
show

// Main movement loop
forever
if <(in combat) = [0]> then
// Normal pathfinding
move towards waypoint
else
// Combat mode
handle combat
end
end
  
    // Custom block: move towards waypoint
define move towards waypoint
// Get current target waypoint coordinates
set [target x v] to (item (current waypoint) of [waypoint x positions v])
set [target y v] to (item (current waypoint) of [waypoint y positions v])

// Calculate direction to target
set [dx v] to ((target x) - (x position))
set [dy v] to ((target y) - (y position))
set [distance v] to (sqrt of (((dx) * (dx)) + ((dy) * (dy))))

if <(distance) > [5]> then
// Move towards waypoint
set [move x v] to (((dx) / (distance)) * (enemy speed))
set [move y v] to (((dy) / (distance)) * (enemy speed))

change x by (move x)
change y by (move y)

// Face movement direction
point in direction ((atan ((move y) / (move x))) + <(move x) < [0]> * [180])
else
// Reached waypoint
if <(current waypoint) < (total waypoints)> then
change [current waypoint v] by [1]
else
// Reached castle
reach castle
end
end
  

⚔️ Step 3: Combat Interruption System

Implement the combat detection and handling:

    // Combat detection (runs continuously)
forever
if <(in combat) = [0]> then
// Check for nearby defenders
set [nearest defender v] to []
set [min distance v] to [999]

// Check all defender sprites
broadcast [check defender distance v]
wait [0.1] seconds

if <not <(nearest defender) = []>> then
// Enter combat
set [in combat v] to [1]
set [combat target v] to (nearest defender)
say [Engaging defender!] for [1] seconds
end
end
end
  
    // Custom block: handle combat
define handle combat
if <not <(combat target) = []>> then
// Face the defender
point towards [combat target v]

// Attack every second
if <(timer) > [1]> then
reset timer
broadcast [enemy attack v]

// Check if defender is still alive
broadcast [check defender alive v]
wait [0.1] seconds

if <(defender alive) = [0]> then
// Defender defeated, resume path
set [in combat v] to [0]
set [combat target v] to []
say [Victory! Continuing path.] for [1] seconds
end
end
else
// No target, exit combat
set [in combat v] to [0]
end
  

🏰 Step 4: Castle Arrival System

Handle what happens when enemies reach the castle:

    // Custom block: reach castle
define reach castle
// Move to castle position
glide [1] secs to x: (castle x) y: (castle y)

// Deal damage to castle
change [castle health v] by [-10]
say [Castle damaged!] for [1] seconds

// Play damage effect
play sound [explosion v]
repeat [5]
set [color v] effect to [25]
wait [0.1] seconds
set [color v] effect to [0]
wait [0.1] seconds
end

// Enemy disappears
set [ghost v] effect to [0]
repeat [10]
change [ghost v] effect by [10]
wait [0.1] seconds
end

hide
delete this clone
  

🎯 Step 5: Advanced Pathfinding Features

Add smooth movement and dynamic pathfinding:

    // Smooth movement with easing
define smooth move to x: (target x) y: (target y)
set [start x v] to (x position)
set [start y v] to (y position)
set [progress v] to [0]

repeat until <(progress) >= [1]>
change [progress v] by [0.05]

// Ease-in-out function
set [eased progress v] to ((progress) * (progress) * (3 - (2 * (progress))))

set [current x v] to ((start x) + ((eased progress) * ((target x) - (start x))))
set [current y v] to ((start y) + ((eased progress) * ((target y) - (start y))))

go to x: (current x) y: (current y)
wait [0.02] seconds
end
  
    // Dynamic path adjustment
define check path obstacles
// Raycast to next waypoint
set [obstacle detected v] to [0]
set [check x v] to (x position)
set [check y v] to (y position)

repeat [20]
change [check x v] by (((target x) - (x position)) / [20])
change [check y v] by (((target y) - (y position)) / [20])

// Check for obstacles at this position
if <touching color [obstacle color v]?> then
set [obstacle detected v] to [1]
// Find alternate path
find alternate route
stop [this script v]
end
end
  

🔧 Step 6: Enemy Spawning System

Create a spawner that generates enemies in waves:

    // Enemy Spawner
when flag clicked
set [wave number v] to [1]
set [enemies per wave v] to [5]
set [spawn delay v] to [2]

forever
// Spawn wave
repeat (enemies per wave)
create clone of [Enemy v]
wait (spawn delay) seconds
end

// Wait for wave to complete
wait until <(enemy count) = [0]>

// Next wave
change [wave number v] by [1]
change [enemies per wave v] by [1]
set [spawn delay v] to ((spawn delay) * [0.9]) // Faster spawning

say (join [Wave ] (wave number)) for [2] seconds
wait [3] seconds
end
  

💡 Pro Tips for Tower Defense Pathfinding

  • Waypoint Optimization: Use fewer waypoints for smoother movement
  • Performance: Limit collision checks to reduce lag
  • Visual Polish: Add rotation and animation to movement
  • Difficulty Scaling: Increase speed and health with each wave
  • Path Variety: Create multiple paths for strategic depth
    // Performance optimization
define optimize performance
// Only check combat every few frames
if <((timer) mod [0.3]) = [0]> then
check for defenders
end

// Reduce visual effects when many enemies
if <(enemy count) > [10]> then
set [effects enabled v] to [0]
else
set [effects enabled v] to [1]
end
  

This system gives you complete control over enemy pathfinding with combat interruption! 🎮

PM

PathfindingMaster

Replied 3 hours later

@AIPathfinding_Expert This is absolutely incredible! 🎉

The waypoint system works perfectly and the combat interruption is exactly what I needed. The enemies now smoothly follow the path and stop to fight defenders when they encounter them. The castle damage system is also working great!

One quick question - how would I add different enemy types with different speeds and behaviors?

ET

EnemyTypes_Specialist

Replied 1 hour later

@PathfindingMaster Great question about enemy variety! Here’s how to implement different enemy types:

    // Enemy type system
when I start as a clone
// Randomly choose enemy type
set [enemy type v] to (pick random [1] to [3])

if <(enemy type) = [1]> then
// Fast Scout
set [enemy speed v] to [5]
set [enemy health v] to [50]
switch costume to [scout v]
set [color v] effect to [50] // Blue tint
end

if <(enemy type) = [2]> then
// Heavy Tank
set [enemy speed v] to [1.5]
set [enemy health v] to [200]
switch costume to [tank v]
set [color v] effect to [-50] // Red tint
end

if <(enemy type) = [3]> then
// Flying Unit (ignores some defenders)
set [enemy speed v] to [3]
set [enemy health v] to [75]
switch costume to [flyer v]
set [can fly v] to [1]
end
  

Each enemy type follows the same pathfinding system but with different stats and behaviors! 🎯

VB

Vibelf_Community

Pinned Message • Moderator

🎮 Ready to Build Advanced Tower Defense Games?

Excellent discussion on pathfinding systems! For those looking to create even more sophisticated tower defense mechanics, our community can help you implement:

  • 🗺️ Multi-path routing and dynamic pathfinding
  • 🏗️ Advanced tower placement and upgrade systems
  • ⚡ Special abilities and power-ups
  • 🎯 Boss enemies with unique movement patterns

📚 Related Discussions

Ready to take your game development skills to the next level? Get personalized guidance from our expert tutors in the Vibelf app!