Godot Version
godot_v.4.4.1-stable
Question
I am having trouble implementing knockback into my game. I have tried to write some code that appears as if it should work, but is not working.
here is the code for the player:
var move_speed : float = 200.0
const JUMP_VELOCITY = -400.0
var state : String = "idle"
var direction : Vector2 = Vector2.ZERO
var gravity = 980
func _process(_delta: float) -> void:
if velocity.y > 0:
state = "fall"
if velocity.y < 0:
state = "jump"
if velocity.x == 0 and is_on_floor():
state = "idle"
player_data.knockback_direction = player_data.knockback_direction.move_toward(Vector2(0,0), 200)
print(player_data.knockback_direction)
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y += gravity * delta
if Input.is_action_just_pressed("Jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
direction.x = Input.get_action_strength("Walk_Right") - Input.get_action_strength("Walk_Left")
if direction:
velocity.x = direction.x * move_speed
else:
velocity.x = move_toward(velocity.x, 0, move_speed)
player_data.player_position = position
velocity += player_data.knockback_direction
move_and_slide()
Here is the code for the enemy hitbox:
extends Area2D
func _on_body_entered(body):
if body.name == "Player" and player_data.player_immunity == false:
player_data.health -= 1
player_data.knockback_direction = (position.direction_to(player_data.player_position)) * 300
player_data.player_immunity = true
print (player_data.knockback_direction)
func _on_body_exited(body):
if body.name == "Player":
player_data.knockback_direction = Vector2(0,0)
Please help.
Never await in perpetual callbacks like _process()
And don’t reduce your knockback_direction in _process() without using delta.
ok, but I don’t think that is relevant to the question.
Yes, to the last argument of move_toward().
But that was meant in addition to what normalized said.
How do you know it isn’t?
You accumulate 60 sleeping coroutines every time player gets hit. They all continue executing at once after one second pause. Are you aware this is happening in your code?
No, but I wasn’t, but i removed it and it didn’t fix anything. But for immunity should I instead make it activate a function that does the same thing?
ok, is the last argument the 200?
Who said just removing it would magically “fix” your bug?
But let’s start from the beginning. You are a programmer, and you’re supposed to care about your code. If you see your code doesn’t display properly when presenting it to others, you should first ask yourself why it’s not displaying properly and want to fix that.
So please, first format your code properly so we can read it by pasting it between ``` tags.
And post the latest version that doesn’t have await in it.
ok i updated the original post
this is my first post so I didn’t know how to do that
Great!
Next, you need to describe the problem precisely. “Not working” is not the precise description of the problem. Tell us what results are you getting vs. what were you expecting to get.
Btw there’s still await in that code.
Also, official GDScript style guide suggests to put one empty line of space between code sections inside the same function, and two empty lines between functions. This makes code tidy and easier to read.
(I removed await in the code)
So, I want to have the player be knocked back in the opposite direction of the enemy when touching it in a predefined distance.
Instead, it always seems to throw the player in the same direction with different distances based on how the player is already moving, what side of the enemy the player is on, and what appears to be random chance.
position property is always relative to node’s parent. When exchanging or calculating positions between nodes that are in different places in scene tree hierarchy you almost always want to use global_position instead.
is this in the player_data.player_position = position?
or the knockback direction code?
Yes, but not only there. The main problem may be in the line where you’re calculating the knockback direction. You’re using area’s local position and player’s local position. Those two are likely in completely different coordinate spaces. When using global_position instead they’ll both be in the same, global, coordinate space, so the direction calculation will be correct.