how to add a damage function?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By hiruy

I have a damage function but I do not know how to enable it.

my code

extends KinematicBody2D

const type = “Player”

signal health_updated(health)
signal killed()

const UP = Vector2(0,-1)
const GRAVITY = 30
const MAXFALLSPEED = 5500
const MAXSPEED = 800
const jumpforce = 1675
const accel = 20

export var max_health = 10
onready var health = max_health setget _set_health
onready var invulnerability_timer = $invulnerabilityTimer

var motion = Vector2()
var facing_right = true
var isAttacking = false;
var is_dead = false

func _physics_process(delta):
if is_dead == false:
motion.y += GRAVITY
if motion.y > MAXFALLSPEED:
motion.y = MAXFALLSPEED

	if facing_right == true:
		$Sprite.scale.x = 10
	else:
		$Sprite.scale.x = -10
	motion.x = clamp(motion.x,-MAXSPEED,MAXSPEED)
	
	
	if Input.is_action_pressed("right") && isAttacking == false:
		motion.x += accel
		facing_right = true
		get_node("attackarea").position = Vector2(25, 1)
		$AnimationPlayer.play("run")
	elif Input.is_action_pressed("left") && isAttacking == false:
		motion.x -= accel
		get_node("attackarea").position = Vector2(-225, 1)
		facing_right = false
		$AnimationPlayer.play("run")
	else:
		motion.x = 0;
		if isAttacking == false:
			$AnimationPlayer.play("idle")
	if is_on_floor():
		if Input.is_action_just_pressed("jump"):
			motion.y = -jumpforce
	if !is_on_floor():
		if motion.y < 0:
			$AnimationPlayer.play("jump")
		elif motion.y > 0:
			$AnimationPlayer.play("fall")
	
	if Input.is_action_just_pressed("attack"):
		$AnimationPlayer.play("attack")
		isAttacking = true;
		$attackarea/attackcolision.disabled = false;
	motion = move_and_slide(motion, UP * delta)

func damage(amount):

if invulnerability_timer.is_stopped():
	invulnerability_timer.start()
	_set_health(health - amount)
	$AnimationPlayer.play("damage")
	$AnimationPlayer.queue("flash")

func kill():
pass

func dead():
kill()
is_dead = true
Vector2(0, 0)
$AnimationPlayer.play(“dead”)
$Timer.start()
emit_signal(“killed”)

func _set_health(value):
var prev_health = health
health = clamp(value, 0, max_health)
if health != prev_health:
emit_signal(“health_updated”, health)

func heal(amount):
if is_dead == false:
health += amount
health = min(health, max_health)
emit_signal(“health_updated”, health)
print(“%s got healed by %s points. Health: %s/%s” % [get_name(), amount, health, max_health])

func _on_invulnerabilityTimer_timeout():
$AnimationPlayer.play(“rest”)

func _on_AnimationPlayer_animation_finished(attack):
$attackarea/attackcolision.disabled = true;
isAttacking = false;

func _on_Timer_timeout():
get_tree().reload_current_scene()

:bust_in_silhouette: Reply From: Gil-Koren

I assume you mean how to call the function when the player should be damaged.

  1. Select the Player node
  2. Go to the “Node” pannel on the right side (the tab next to the Inspector)
  3. Find the “body_entered” signal or whatever signal seems apropriate to your damage system.
  4. Right click the signal and connect it to the player Script.
  5. in the newly created function, call the damage function with your wanted paramter.

If you want to pass each enemies damage and avoid being damaged by other collisions, I recommend adding your enemies to a Group (Inside the node tab next to signals), and add a variable called damage to them, and instead of calling the damage function, check wether the collision is from the enemy group using the is_in_group(“Enemy”) Method on the entered body passed by the collision signal and the call the damage function and pass that enemy’s damage variable.

If you have anymore question or getting stuck feel free to keep asking :slight_smile:

thanks. but after the health is = 1 it will stop taking damage it does not below is there a fix? thanks for your answer I really appreciate it. (and I commented on the heal function that didn’t fix it)

hiruy | 2022-07-29 14:23

It seems your problem is in the set health function. The code clamps it between 0 and max health, not allowing it to go down further.
You have a dead function as well, so this set health function should do the job:

func _set_health(new_health):
     if new_health > 0:
        emit_signal("health_updated", new_health)
    else:
        dead()

Notice code isn’t indented well here, so just re-indent when you take the code.

Gil-Koren | 2022-07-29 14:48

bro, I can’t thank you enough I was looking through the web for 2 days you helped me very much. but my damage function isn’t working

hiruy | 2022-07-29 15:20

Happy to help :slight_smile:

Gil-Koren | 2022-07-29 15:31