- Edited
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