Godot Version
v4.2.1.stable.official [b09f793f5]
Question
Hi! I’ve been following some guides (this, and it’s sequel mainly) in an attempt to use classes to implement a flexible damage/health system, and I’m having some trouble. Specifically, the enemy doesn’t seem to be hurting the player whatsoever (tried changing the damage to 50, to see if it was just hurting it once, but nothing). For context, this is my first ever project (So be patient with any idiocy, please) and I’m making a top-down 2d twin stick shooter. In this specific example, I’m trying to make my enemy hurt my player, for 5 damage, when they’re colliding. I had this working already, using the method shown here, but that was far too rigid and restrictive. Below is the code:
In a file named Attack.gd:
extends Node
class_name Attack
var attack_damage: float
var knockback_force: float
var attack_position: Vector2
In the enemy script (I’ve tried to cut out things that aren’t relevant):
extends CharacterBody2D
class_name Enemy
var attack_damage = 50
var knockback_force = 0.0
var health = 10
#Attack code
func _on_body_entered(body):
if body.has_method("take_player_damage"):
var attack = Attack.new()
attack.attack_damage = attack_damage
attack.knockback_force = knockback_force
attack.attack_position = global_position
body.take_player_damage(attack)
In the player script (same):
extends CharacterBody2D
var health = 100.0
func take_player_damage(attack: Attack, delta):
health -= attack.attack_damage * delta
I have got this working for hurting the enemy with bullets. Here is the script for that:
(The same attack.gd)
The bullet script:
extends Area2D
#starts "empty" and "fills up" as the bullet travels
var travelled_distance = 0
var attack_damage = 1
var knockback_force = 100
func _physics_process(delta):
const SPEED = 250
const RANGE = 6000
#defining a variable name direction. Direction is equal to: the right direction (for the bullet. ei. where the "right hand" of the bullet would be) rotated by the rotation predefined rotation of the bullet.
var direction = Vector2.RIGHT.rotated(rotation)
position += direction * SPEED * delta
#calculate the traveled distance based on the "SPEED" constant, and if the travelled distance exceeds the "RANGE" constant, delete bullet
travelled_distance += SPEED
if travelled_distance > RANGE:
queue_free()
#if the bullet enters a body with the "take_damage" method (ei. function) run "take_damage" and remove bullet.
func _on_body_entered(body):
if body.has_method("take_damage"):
var attack = Attack.new()
attack.attack_damage = attack_damage
attack.knockback_force = knockback_force
attack.attack_position = global_position
body.take_damage(attack)
queue_free()
The enemy script (Yet again, tried to only include was what relevant for the sake of conciseness)
var health = 10
func take_damage(attack: Attack):
health -= attack.attack_damage
#Turn sprite red with .5 alpha (pure red was decided to be too contrasty)
$AnimatedSprite2D.modulate = Color(1,0,0,.5)
#starts the timer for the color, so that it flashes for .5 seconds
hurt_timer.start()
velocity = (global_position - attack.attack_position).normalized()*attack.knockback_force
if health == 0:
#stops the Adventurer
AdventurerSpeed = 0
#Plays animation of Adventurer sprite fading away
anim.play("Dying")
#Wait 1 second
await get_tree().create_timer(1).timeout
#delete the Adventurer
queue_free()
Any help would be much appreciated. I’m still trying to wrap my head around GDScript (This is also the first time I’ve really tried to learn and use a programming language) and I’m finding myself frequently lost. If you could please be as detailed in your explanations of how I’m stupid, I’d much appreciate it