Godot Version
Godot_v4,3
Question
What if i want the enemy die with more than 1 hit when i shoot him ?
What is the code/ script for this
I want to hit them like 10 times
Godot_v4,3
What if i want the enemy die with more than 1 hit when i shoot him ?
What is the code/ script for this
I want to hit them like 10 times
var health = 10
func got_hit():
health -= 1
if health <= 0:
die() # whatever you do for a "dead" object; play sounds, sprite fx, whatever
Should I put this code in the bullet script or the enemy script?
The enemy script, presumably. It’s basically the old Dungeons & Dragons/RPG concept of “hit points”.
You could potentially also give different shots different strength levels, so (say) if the player holds down the fire button for a bit they get a “charge shot” that does 5 damage; you then just subtract 5 rather than 1.
Ideally, in your enemy script, you’d have something like:
var health = 10
var incoming_damage = 0
func take_damage(amount: int): # call this from your collision response
incoming_damage += amount
func _process(delta: float):
if incoming_damage != 0: # We took a hit!
if incoming_damage >= health: # DEAD!
add_to_player_score()
play_die_sound()
spawn_explode_anim()
[...whatever else...]
delete_me()
else: # Not enough to kill us...
health -= incoming_damage
incoming_damage = 0 # Zero the processed damage.
play_stagger_anim()
[...whatever else...]
I can’t get it to work still enemy die with one hit can you fix that for me I’m really a noob lol
this is the script for bullet
extends Area2D
@export var speed = 750
func _physics_process(delta):
position += transform.x * speed * delta
func _on_bullet_body_entered(body):
if body.is_in_group("mobs"):
body.queue_free()
queue_free()
and here is the script for enemy
extends CharacterBody2D
var speed = 50
func _ready():
velocity = transform.x * speed
func _physics_process(delta):
# move_and_slide()
# var collision = get_last_slide_collision()
# if collision:
# print("bouncing ", collision.get_collider().name, collision.get_normal())
# velocity = velocity.bounce(collision.get_normal())
# rotation = velocity.angle()
var collision = move_and_collide(velocity * delta)
if collision:
velocity = velocity.bounce(collision.get_normal())
That body.queue.free()
in the bullet collision handler is killing (well, really, deleting) the thing it hits. Instead of that, you want to let body
know that it has taken damage, and then let whatever took damage decide what to do about it.
I think you want this to be something like:
Bullet:
var damage = 1 # Raise this to hit harder.
[...stuff...]
func _on_body_bullet_entered(body):
if body.is_in_group("mobs"): # Did we hit a mob?
body.got_hit(damage) # Damage it!
queue_free() # We're done.
Enemy:
var health = 10
var incoming_damage = 0
[...stuff...]
func got_hit(damage: int):
# Just accumulate; we may take multiple hits this update.
incoming_damage += damage
func _physics_process(delta: float):
[...stuff...]
# Deal with damage.
if incoming_damage:
if incoming_damage >= health: # Dead!
# do score, effects, hit sounds &c. here.
queue_free()
else: # Still alive...
# do stagger anims, effects &c. here.
health -= incoming_damage # Apply the damage.
incoming_damage = 0 # We've processed it, it can go.
[...stuff...]
You can do all sorts of stuff with this basic framework. You could, for example, use float
instead of int
for health, and then you could have mobs with regenerating health; something in Enemy like:
const MAX_HEALTH = 10.0
const REGENERATE = 0.25 # Recover 1hp every 4 seconds.
var health = MAX_HEALTH
var incoming_damage = 0.0
[...stuff...]
func got_hit(damage: float):
incoming_damage += damage
[...stuff...]
func _physics_process(delta: float):
[...stuff...]
if incoming_damage > 0.0:
[...same as above...]
else: # Didn't get hit, regenerate if we need to...
# Need to scale by delta so regenerate is consistent over time...
health += clampf(health + REGENERATE * delta), 0.0, MAX_HEALTH)
[...stuff...]
You can also do things like iframes (that is, making something invincible for a little while after taking a hit). That’s usually something for the player rather than mobs, but the idea is the same:
Enemy:
const IFRAME_TIME = 0.8
var iframes = 0.0
[...stuff...]
if incoming_damage:
if iframes >= 0.0:
incoming_damage = 0 # Invincible! Ignore!
else: # Vincible! We get hurt!
if incoming_damage >= health: # Dead!
[...as above...]
else: # Still alive!
[...other stuff...]
iframes = IFRAME_TIME # Set up invulnerability.
# Invincibility countdown.
iframes = clampf(iframes - delta, 0.0, IFRAME_TIME)
[...stuff...]
There are lots of things you can do with a system like this. You can make shots that get weaker over time:
Bullet:
const MAX_LIFE = 2.0 # Done after 2 seconds...
var damage = 1.0
var lifetime = 0.0
_func physics_process(delta: float):
[...stuff...]
lifetime += delta
if lifetime > MAX_LIFE: # Shot ran out of power, delete it.
queue_free()
func _on_bullet_body_entered(body):
if body.is_in_group("mobs"):
# Scale the damage based on lifetime:
body.got_hit(damage * (MAX_LIFE - (lifetime / MAX_LIFE)))
queue_free()
There are endless possibilities.