• Godot Help
  • Godot 4 2D top-down ; knockback effect problems

Hello, I am completely new to making games, started with some tutorials on Godot 4. I finished the tutorial and decided I will try moving further with what was built and wanted to add more things to the game. I am stuck on adding knockback when enemy is attacked.
First of all I don't even know how to ask for help, this is my first post ever. I asked the AI chat to help me for couple of days but I need to ask for help real community or just give up. I am not sure if you want me to upload my whole game (how?) or just the code I am strugging with so I will start with the code.

The knocback when enemy is attacked works quite correctly when I attack from left of right, when attacking from above the player is teleported along with the enemy (rarely on long distance) on his knockback. When attacking from below sometimes it makes enemy stick to the player preventing the player from moving up. I don't know the source of the bugs but maybe my code should be not 4-ways oriented but also taking into consideration getting attacked from 45 degrees angles like top-left? Below is the code of enemy node, let me know what else can I do to help you helping me easier:

[Edit] I wanted to add the weird things happen when I push towards the enemy, which I think players usually do, they push the arrow towards the enemy and attack them at the same time. When I stand still nothing weird happens. Maybe there is something with collision shapes but I tried like 100 cominations making them bigger/smaller/different shape and so on and nothing helped.

extends CharacterBody2D

var speed = 50
var player_chase = false
var player = null

var health = 100
var player_inattack_zone = false
var can_take_damage = true
var knockback_force = Vector2(15, -15)


func _physics_process(delta):
	move_and_slide()
	deal_with_damage()
	update_health()

	if player_chase:
		var direction = (player.position - position).normalized()
		var distance_to_player = position.distance_to(player.position)

		if can_take_damage == true:
			$AnimatedSprite2D.play("walk")

		if distance_to_player > 14.5:
			position += direction * speed * delta

		if(player.position.x - position.x) < 0:
			$AnimatedSprite2D.flip_h = true
		else:
			$AnimatedSprite2D.flip_h = false
	else:
		$AnimatedSprite2D.play("idle")



func _on_detection_area_body_entered(body):
	player = body
	player_chase = true

func _on_detection_area_body_exited(body):
	player = null
	player_chase = false

func enemy():
	pass

func _on_enemy_hitbox_body_entered(body):
	if body.has_method("player"):
		player_inattack_zone = true

func _on_enemy_hitbox_body_exited(body):
	if body.has_method("player"):
		player_inattack_zone = false


#below works with minor bugs
func deal_with_damage():
	if player_inattack_zone and global.player_current_attack == true:
		if can_take_damage == true:
			health = health - 20
			print("slime health = ", health)

			# Play the "damage" animation
			$AnimatedSprite2D.play("damage")
			
#			var knockbackDirection = (position - player.position).normalized()
#			var knockbackVelocity = knockbackDirection * knockback_force
#			move_and_collide(knockbackVelocity)

			var horizontal_knockback_force = Vector2(knockback_force.x, 0)
			var vertical_knockback_force = Vector2(0, knockback_force.y)

			if abs(player.position.x - position.x) > abs(player.position.y - position.y):
				position += horizontal_knockback_force * -sign(player.position.x - position.x)
			elif abs(player.position.x - position.x) < abs(player.position.y - position.y):
				position += vertical_knockback_force * sign(player.position.y - position.y)

			$take_damage_cooldown.start()
			can_take_damage = false

			if health <= 0:
				self.queue_free()

func _on_take_damage_cooldown_timeout():
	can_take_damage = true
	
func update_health():
	var healthbar = $healthbar
	
	healthbar.value = health
	
	if health >= 100:
		healthbar.visible = false
	else:
		healthbar.visible = true

If what you want is for the enemy to move backwards when attacked (as happens with the player when attacked in games like ghost and goblins), what you should do is say that their movement in x is affected at the moment of attack. receive damage (of course this will change depending on which direction the enemy is looking, in my case I tell him that it depends on whether flip H is true or false), sorry for some error in the syntax of this message I am using the google translator