how should i make a kinematicbody 2D pull back for specific x and y coordinates ?

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

Hi Godot People…
i want enemy to pull back after it gets hurt (on both x and y axis). i write this code in process function. but it seems after feeling the punch, i should hold the hit key in order to enemy goes back, if i just press and release the hit button, enemy stop after releasing the key, which i think process function is the reason, but if i want to move the code for ex to input function, there is no any delta for changing speed of pulling back. what should i do to make it right? thank you :slight_smile:

(Godot v2.1.5)

 if animations.get_current_animation() == "Hurt":
    if (self.get_global_pos().x>enemy.get_global_pos().x):
       if (enemy_animations.get_current_animation() == "L_Fist"):
          self.move(Vector2(self.get_global_pos().x-OS.get_window_size().x/10,
                    self.get_global_pos().y-OS.get_window_size().y/10).normalized()*speed*delta)
       if (self.is_colliding()):
          move(get_collision_normal().slide(self.move(Vector2(self.get_global_pos().x-OS.get_window_size().x/10,
                                                      self.get_global_pos().y-OS.get_window_size().y/10).normalized()*speed*delta)))
       if (enemy_animations.get_current_animation() == "R_Fist"):
          self.move(Vector2(self.get_global_pos().x-OS.get_window_size().x/10,
                    -(self.get_global_pos().y-OS.get_window_size().y/10)).normalized()*speed*delta)
       if (self.is_colliding()):
          move(get_collision_normal().slide(self.move(Vector2(self.get_global_pos().x-OS.get_window_size().x/10,
                                                      -(self.get_global_pos().y-OS.get_window_size().y/10)).normalized()*speed*delta)))

    if (self.get_global_pos().x<enemy.get_global_pos().x):
       if (enemy_animations.get_current_animation() == "L_Fist"):
          self.move(-Vector2(self.get_global_pos().x-OS.get_window_size().x/10,
                    self.get_global_pos().y-OS.get_window_size().y/10).normalized()*speed*delta)
       if (self.is_colliding()):
          move(get_collision_normal().slide(self.move(-Vector2(self.get_global_pos().x-OS.get_window_size().x/10,
                                                      self.get_global_pos().y-OS.get_window_size().y/10).normalized()*speed*delta)))
       if (enemy_animations.get_current_animation() == "R_Fist"):
          self.move(-Vector2(self.get_global_pos().x-OS.get_window_size().x/10,
                    -(self.get_global_pos().y-OS.get_window_size().y/10)).normalized()*speed*delta)
       if (self.is_colliding()):
          move(get_collision_normal().slide(self.move(-Vector2(self.get_global_pos().x-OS.get_window_size().x/10,
                                                      -(self.get_global_pos().y-OS.get_window_size().y/10)).normalized()*speed*delta)))
:bust_in_silhouette: Reply From: Bishop

Hi,…you have Area2D node for a triggering player’s hits?
Area emits signals…then if player hit the enemy••••signal hit•••••>play animation,move
enemy…you can use only animation…play(“Hurt”) animation and animate translation x and y enemy’s node.
…you can also write your own signals.
…you can also use raycasting …the options are more, you have to choose the easiest one!!
…and use a _fixed_process (delta):

hi Bishop :slight_smile:
i dont have any problem to detect collision and hit/hurt. my code for hitting/hurting and detecting collision works properly.
i want enemy character for example, when detect collision (feel hurt), goes back on x and y axis. i wrote the code above and put it in fixed process (or process)… the problem is i should press the hit button and hold the key in order to enemy goes back. if i release the button, enemy stops and does not go to the desire coordinates, if i press hit button and release it quickly, enemy goes back just with that very short pressing time. the rediculous thing is, if i just change the length of hit animation (i mean the length of “L_Fist or R_Fist”) and set it to 5seconds for ex, (2seconds did not work), and then hit the enemy, it goes back for 5 seconds. this is what i want to fix. (when feel collision (hurt) goes back for specific x and y…)
how should enemy go back independently after feeling collision and go to the desire x and y coordinate?

i put the entire code of _fixed_process() function here… this is the player’s code and enemy punch the player, thanks

func _fixed_process(delta):
     velocity = Vector2()
     if Input.is_action_pressed("ui_right"):
        velocity.x += 1
     if Input.is_action_pressed("ui_left"):
        velocity.x -= 1
     if Input.is_action_pressed("ui_down"):
        velocity.y += 1
     if Input.is_action_pressed("ui_up"):
        velocity.y -= 1
     if velocity.length() > 0:
        velocity = velocity.normalized() * speed
     var motion = move(velocity * delta)
     if (is_colliding()):
        var n = get_collision_normal()
        motion = n.slide(motion)
        velocity = n.slide(velocity)
        move(motion)
     
     if animations.get_current_animation() == "Hurt":
        if (self.get_global_pos().x>enemy.get_global_pos().x):
           if (enemy_animations.get_current_animation() == "L_Fist"):
              var dizzy_motion = global_translate(Vector2(get_pos().x - OS.get_window_size().x/10,
                                              get_pos().y - OS.get_window_size().y/10).normalized()*speed*delta)
              if is_colliding():
                 var dizzy_n = get_collision_normal()
                 dizzy_motion = dizzy_n.slide(dizzy_motion)
                 dizzy_n.slide(Vector2(get_pos().x - OS.get_window_size().x/10,
                                              get_pos().y - OS.get_window_size().y/10).normalized()*speed)
                 move(dizzy_motion)
           if (enemy_animations.get_current_animation() == "R_Fist"):
              var dizzy_motion = move(Vector2(get_pos().x - OS.get_window_size().x/10,
                                              -(get_pos().y - OS.get_window_size().y/10)).normalized()*speed*delta)
              if is_colliding():
                 var dizzy_n = get_collision_normal()
                 dizzy_motion = dizzy_n.slide(dizzy_motion)
                 dizzy_n.slide(Vector2(get_pos().x - OS.get_window_size().x/10,
                                              -(get_pos().y - OS.get_window_size().y/10)).normalized()*speed)
                 move(dizzy_motion)
       
        if (self.get_global_pos().x<enemy.get_global_pos().x):
           if (enemy_animations.get_current_animation() == "L_Fist"):
              var dizzy_motion = move(-Vector2(get_pos().x - OS.get_window_size().x/10,
                                              get_pos().y - OS.get_window_size().y/10).normalized()*speed*delta)
              if is_colliding():
                 var dizzy_n = get_collision_normal()
                 dizzy_motion = dizzy_n.slide(dizzy_motion)
                 dizzy_n.slide(-Vector2(get_pos().x - OS.get_window_size().x/10,
                                              get_pos().y - OS.get_window_size().y/10).normalized()*speed)
                 move(dizzy_motion)
           if (enemy_animations.get_current_animation() == "R_Fist"):
              var dizzy_motion = move(-Vector2(get_pos().x - OS.get_window_size().x/10,
                                              -(get_pos().y - OS.get_window_size().y/10)).normalized()*speed*delta)
              if is_colliding():
                 var dizzy_n = get_collision_normal()
                 dizzy_motion = dizzy_n.slide(dizzy_motion)
                 dizzy_n.slide(-Vector2(get_pos().x - OS.get_window_size().x/10,
                                              -(get_pos().y - OS.get_window_size().y/10)).normalized()*speed)
                 move(dizzy_motion)

p.s: bishop you said “animate translation x and y enemy’s node” how should i do that? these characters are kinematicbody, so they should fell collide and slide… is there a way to put these things in animation player??

mdswamp | 2018-09-29 19:25

ok… i created another project and used the code above on default godot sprite. code works, not the way i want (i want to stop in specific coordinates), but it works anyway… i think problem apears when i use animation in if conditions…

mdswamp | 2018-09-30 00:00

:bust_in_silhouette: Reply From: mdswamp

finally i succeeded to write the right logic code for this behavior. for those (beginners like me) who want to do something like this…
1- create a timer for pull back duration
2- use something like boolean variable(s) in your collision function(s) to inform your _(fixed)_process(delta) that collision has happened, and start your timer in collision function(s)
3- write your _(fixed)_process(delta) almost like this:
:slight_smile:

func _fixed_process(delta):
     var velocity = Vector2()
     if (l_fist == true):
        if (head_fr.get_global_pos().x>enemy_head_fr.get_global_pos().x):
           velocity += Vector2(2,6)
        if (head_fr.get_global_pos().x<enemy_head_fr.get_global_pos().x):
           velocity += -Vector2(2,6)
     elif (r_fist == true):
        if (head_fr.get_global_pos().x>enemy_head_fr.get_global_pos().x):
           velocity += Vector2(2,-6)
        if (head_fr.get_global_pos().x<enemy_head_fr.get_global_pos().x):
           velocity += -Vector2(2,-6)
     else:
        if Input.is_action_pressed("p02_right"):
           velocity.x += 1
        if Input.is_action_pressed("p02_left"):
           velocity.x -= 1
        if Input.is_action_pressed("p02_down"):
           velocity.y += 1
        if Input.is_action_pressed("p02_up"):
           velocity.y -= 1
     if velocity.length() > 0:
        velocity = velocity.normalized() * speed
     var motion = move(velocity * delta)
     if (is_colliding()):
        var n = get_collision_normal()
        motion = n.slide(motion)
        velocity = n.slide(velocity)
        move(motion)