Godot Version
4.3
Question
I’m making a killzone script for my new game but when I tested it my game crashed pls help, here’s the code.
extends Area2D
#variables
@onready var health = 20
@onready var timer = $Timer
@onready var damaged = true
@onready var lambdas_ref = func _on_timer_timeout() -> void:
damaged = true
#functions
func _on_body_entered(body: Node2D) -> void:
while(damaged):
health -= 1 #<-- subtracts health
var damaged = false
timer.start
print(health)
if health <= 0:
health = 0
print("You Died!")
get_tree().reload_current_scene()
elif health <= 10:
print("You Are Hurt.")
else:
print("You Are Fine.")
Ah, ok. Have a look at this:
var damaged = true
[...]
while(damaged):
[...]
var damaged = false # OOPS
[...]
You’ve got var damaged
in the while
loop. That makes a new variable in that scope called damaged
and assigns false
to it, but the while()
loop is operating on the global scope damaged
. The loop will never end.
My suggestions:
- make that
while()
an if
– it’s not intentionally being used to loop
- strip
var
off var damaged
inside _on_body_entered()
Thanks but now the killzone just damages the player once but I want it to keep taking 1 health off every second spent in the killzone. If I wanted that to happen the I wouldn’t have the lambda.
You should try a for loop.
Also, is your character being handled in a class? if so you could probably set up a death function & have it be public, so if you change anything about the death screen/function, then you won’t have to modify a lot of scripts.
Also to avoid putting the script in a lot of bodies, you should have another for loop iterate and add a key (in this case, body) to a dictionary full of bodies (or you can manually place them), and then have a general on body entered function, where it checks if the body is a member of the bodies dictionary.
It might be much, but it saves you from having to plant the script into every new body.
In that case, you probably want to do this differently. It looks like you’re checking if the area was entered and then firing this off. What you probably want to do is, every update check if you’re within the area, and do a bit of damage if so.
A loop inside the function is going to run to completion within a single update, which will be an instant kill.
could you show what that code could look like?
For example:
const DAMAGE_PER_SEC = 5.0
const REGEN_PER_SEC = 0.1
const MAX_HEALTH = 20.0
var body_is_in = false
var health = MAX_HEALTH
func _on_body_entered(body: Node2D) -> void:
body_is_in = true
func _on_body_exited(body: Node2D) -> void:
body_is_in = false
func _process(delta: float) -> void:
if body_is_in:
health -= DAMAGE_PER_SEC * delta
elif health < MAX_HEALTH:
health = clampf(health + (REGEN_PER_SEC * delta), 0.0, MAX_HEALTH)
if health <= 0.0:
print("O! I Die!")