Skip to content

How to prevent enemies from taking multiple damage hits in Scratch

💡 Struggling with collision detection and damage systems in your games? 🚀 Get Expert Help

CS

CombatSystem_Dev

Posted on July 22, 2025 • Advanced

⚔️ Enemy taking multiple damage hits - need help!

I’m working on a combat system and having issues with my collision detection. When a projectile hits an enemy, it deals damage multiple times instead of just once.

Here’s my current collision code:

define CheckCollision
set [check index] to (0)
repeat (length of [ProjectileCollision])
if <touching (item (check index) of [ProjectileCollision])?>
switch costume to (Detect)
if <touching (item (check index) of [ProjectileCollision])?>
change [Clone health] by (item (check index) of [ProjectileDamage])
end
switch costume to (Costume)
end
end

The problem is that the enemy takes 2x more damage than it should because the projectile doesn’t disappear fast enough. The collision detection runs multiple times before the projectile is removed.

How can I fix this so each projectile only deals damage once per enemy? 🤔

DS

DamageSystem_Expert

Replied 2 minutes later • ⭐ Best Answer

@CombatSystem_Dev This is a very common issue in game development! The problem is that collision detection runs every frame, but projectiles take time to be removed. Here are several robust solutions:

🛡️ Damage Prevention System Architecture

Here’s how a proper damage system should work:

flowchart TD A[🎯 Projectile Hits Enemy] --> B{Enemy has invincibility?} B -->|Yes| C[❌ No Damage] B -->|No| D[💥 Apply Damage] D --> E[🛡️ Start Invincibility Timer] E --> F[📝 Record Hit Source] F --> G[⏰ Invincibility Active] G --> H{Timer Expired?} H -->|No| I[🚫 Block All Damage] H -->|Yes| J[✅ Remove Invincibility] I --> K[⏱️ Decrease Timer] K --> H J --> L[🎯 Ready for Next Hit] C --> L style A fill:#e1f5fe style D fill:#ffebee style E fill:#e8f5e8 style I fill:#fff3e0

🛡️ Solution 1: Invincibility Frames (Recommended)

The most professional approach - give enemies temporary invincibility after taking damage:

    // In your enemy sprite
when flag clicked
set [invincible_timer v] to [0]
set [max_invincible_time v] to [30] // 30 frames = 0.5 seconds

forever
// Decrease invincibility timer
if <(invincible_timer) > [0]> then
change [invincible_timer v] by [-1]

// Visual feedback during invincibility
if <((invincible_timer) mod [6]) < [3]> then
set [ghost v] effect to [50]
else
set [ghost v] effect to [0]
end
else
set [ghost v] effect to [0]
end
end

// Updated collision detection
define CheckCollision
set [check_index v] to [1]
repeat (length of [ProjectileCollision v])
set [projectile_name v] to (item (check_index) of [ProjectileCollision v])

if <<touching (projectile_name)?> and <(invincible_timer) = [0]>> then
// Apply damage
set [damage_amount v] to (item (check_index) of [ProjectileDamage v])
change [Clone_health v] by (damage_amount)

// Start invincibility period
set [invincible_timer v] to (max_invincible_time)

// Visual/audio feedback
play sound [hit v]

// Optional: knockback effect
broadcast [enemy_hit v]

stop [this script v] // Exit after first hit
end

change [check_index v] by [1]
end
  

🎯 Solution 2: Projectile-Specific Hit Tracking

Track which projectiles have already hit this enemy:

    // In your enemy sprite - initialize
when flag clicked
delete all of [hit_by_projectiles v]

// Updated collision detection with hit tracking
define CheckCollision
set [check_index v] to [1]
repeat (length of [ProjectileCollision v])
set [projectile_name v] to (item (check_index) of [ProjectileCollision v])

if <touching (projectile_name)?> then
// Check if we've already been hit by this projectile
if <not <[hit_by_projectiles v] contains (projectile_name)?>> then
// First time being hit by this projectile
add (projectile_name) to [hit_by_projectiles v]

// Apply damage
set [damage_amount v] to (item (check_index) of [ProjectileDamage v])
change [Clone_health v] by (damage_amount)

// Feedback
play sound [hit v]
broadcast [enemy_hit v]
end
else
// Not touching anymore - remove from hit list
if <[hit_by_projectiles v] contains (projectile_name)?> then
delete (item # of (projectile_name) in [hit_by_projectiles v]) of [hit_by_projectiles v]
end
end

change [check_index v] by [1]
end
  

⚡ Solution 3: Projectile-Side Management

Let projectiles track what they’ve hit:

    // In your projectile sprite
when I start as a clone
delete all of [enemies_hit v]
set [can_hit_multiple v] to [false] // Set to true for piercing projectiles

forever
// Check collision with enemies
if <touching [Enemy v]?> then
set [enemy_id v] to [Enemy] // Or get specific enemy ID

if <not <[enemies_hit v] contains (enemy_id)?>> then
// First time hitting this enemy
add (enemy_id) to [enemies_hit v]

// Send damage info to enemy
broadcast (join [damage_] (my_damage))

// If projectile can't hit multiple enemies, destroy it
if <(can_hit_multiple) = [false]> then
delete this clone
end
end
end
end

// In enemy sprite - receive damage
when I receive [damage_10 v] // Example for 10 damage
if <touching [Projectile v]?> then
change [health v] by [-10]
play sound [hit v]
end
  

🔄 Solution 4: Cooldown System for Multiple Projectiles

For handling multiple different projectile types:

    // Advanced system with per-projectile-type cooldowns
when flag clicked
// Initialize cooldown lists
delete all of [projectile_types v]
delete all of [cooldown_timers v]

// Add projectile types
add [bullet] to [projectile_types v]
add [0] to [cooldown_timers v]

add [missile] to [projectile_types v]
add [0] to [cooldown_timers v]

add [laser] to [projectile_types v]
add [0] to [cooldown_timers v]

forever
// Decrease all cooldown timers
set [timer_index v] to [1]
repeat (length of [cooldown_timers v])
if <(item (timer_index) of [cooldown_timers v]) > [0]> then
replace item (timer_index) of [cooldown_timers v] with ((item (timer_index) of [cooldown_timers v]) - [1])
end
change [timer_index v] by [1]
end
end

// Check collision with cooldown system
define check collision with (projectile_type)
set [type_index v] to (item # of (projectile_type) in [projectile_types v])
set [current_cooldown v] to (item (type_index) of [cooldown_timers v])

if <<touching (projectile_type)?> and <(current_cooldown) = [0]>> then
// Apply damage based on projectile type
if <(projectile_type) = [bullet]> then
change [health v] by [-10]
replace item (type_index) of [cooldown_timers v] with [20] // 20 frame cooldown
else
if <(projectile_type) = [missile]> then
change [health v] by [-25]
replace item (type_index) of [cooldown_timers v] with [60] // 60 frame cooldown
end
end

play sound [hit v]
end
  

💡 Pro Tips for Damage Systems

  • Visual Feedback: Use flashing or color effects during invincibility
  • Audio Cues: Different sounds for hits vs blocked hits
  • Knockback: Push enemies away slightly when hit
  • Damage Numbers: Show floating damage text for player feedback
  • Performance: Use broadcasts instead of checking every frame when possible

The invincibility frames method (Solution 1) is the most commonly used in professional games because it feels natural to players and prevents all forms of damage stacking! 🎮

CS

CombatSystem_Dev

Replied 15 minutes later

@DamageSystem_Expert This is incredibly helpful! 🤩

I implemented the invincibility frames solution and it works perfectly! The flashing effect during invincibility is a nice touch that gives great visual feedback to the player.

My enemies now take exactly the right amount of damage, and the combat feels much more polished. Thank you so much! 🙏

GD

GameDev_Mentor

Replied 30 minutes later

Excellent solutions! 👏 One additional tip: consider adding different invincibility durations for different damage types.

For example, small bullets might give 0.3 seconds of invincibility, while big explosions give 1 second. This prevents rapid-fire weapons from being overpowered while still allowing meaningful damage from heavy attacks.

Also, some games use “damage reduction” during invincibility instead of complete immunity - worth experimenting with! 🎯

VB

Vibelf_Community

Pinned Message • Moderator

⚔️ Advanced Combat Systems

Fantastic discussion on damage prevention! For those building sophisticated combat systems, our tutors can help you implement:

  • 🛡️ Complex damage types and resistances
  • ⚡ Advanced collision optimization
  • 🎯 Hitbox and hurtbox systems
  • 💥 Combo systems and damage scaling
  • 🎮 Professional game feel and juice

📚 Related Topics

Ready to create professional-grade combat systems? Get personalized guidance from our game development experts!