# how to make kinematicbody2d jump along circular arc?

Attention Topic was automatically imported from the old Question2Answer platform.

I am trying to make enemy like a slime which jump towards direction in 2d platformer.
following code is a current enemy script.
I want enemy to jump once in every 3 seconds, so in func _on_Timer_timeout(), I put enemy_state = state.JUMP to make it jump along circula arc.
However, it goes upward continuously. any solution?

``````extends KinematicBody2D

var speed = 0
var gravity = 800
var jump_speed = 100
var jump_height = 350
var direction = 1
var velocity = Vector2.ZERO

enum state {IDLE, JUMP}

var enemy_state = state.IDLE

enemy_state = state.IDLE
\$Jump_Timer.start()
pass

func _physics_process(delta):

match enemy_state:
state.IDLE:
if velocity.x>0:
\$Position2D.scale.x=1
elif velocity.x<0:
\$Position2D.scale.x=-1

velocity.y += gravity * delta
velocity.x = speed * direction
velocity = move_and_slide(velocity, Vector2.UP)

if is_on_wall() or not \$Position2D/FloorRay.is_colliding() and is_on_floor():
direction = direction * -1

state.JUMP:
if velocity.x>0:
\$Position2D.scale.x=1
elif velocity.x<0:
\$Position2D.scale.x=-1

velocity.x = jump_speed * direction
velocity.y = -jump_height
velocity.y += gravity * delta
velocity = move_and_slide(velocity, Vector2.UP)
if is_on_wall() or not \$Position2D/FloorRay.is_colliding() and is_on_floor():
direction = direction * -1

func _on_Timer_timeout():
#velocity.y = -jump_height
#velocity.x = jump_speed * direction
#velocity = move_and_slide(velocity, Vector2.UP)
enemy_state = state.JUMP
print("Do Jump")
\$Jump_Timer.start()
``````

Your enemy starts in IDLE state, but once it’s in JUMP state, there is nothing setting it back to being IDLE.

If you are alright with parabolic jump arcs, here is an excellent talk about it: https://www.youtube.com/watch?v=hG9SzQxaCm8
I’ve implemented this in my games, you can use this if you like:
https://github.com/zhyrin0/through-the-looking-glass/blob/main/src/character/character_base.gd ← defines the parameters of the jump
https://github.com/zhyrin0/through-the-looking-glass/blob/main/src/character/player/player.gd ← implements jump physics.

Another cheeky way you could do it is have a `Path2D` with a circular path, and when the enemy jumps, a `PathFollow2D` goes along the path and you translate your enemy based on that.

Hi zhrin. Thank you for great sources for jump!
the following code I have made works complete fine, as the jump is only triggered when the key is pressed. but enemy doesnt press the key, and i have no idea how to make it jump once in every three seconds.

``````extends KinematicBody2D
var speed = 50
var gravity = 800
var direction = 1

var move_speed = 50
export var jump_height : float
export var jump_time_to_peak : float
export var jump_time_to_descent : float

onready var jump_velocity : float = ((2.0 * jump_height) / jump_time_to_peak) * -1.0
onready var jump_gravity : float = ((-2.0 * jump_height) / (jump_time_to_peak * jump_time_to_peak)) * -1.0
onready var fall_gravity : float = ((-2.0 * jump_height) / (jump_time_to_descent * jump_time_to_descent)) * -1.0

var velocity = Vector2.ZERO

func get_gravity() -> float:
return jump_gravity if velocity.y < 0.0 else fall_gravity

func _physics_process(delta):
if velocity.x>0:
\$Position2D.scale.x=1
elif velocity.x<0:
\$Position2D.scale.x=-1

velocity.y += get_gravity() * delta
velocity.x = speed * direction
velocity = move_and_slide(velocity, Vector2.UP)

if is_on_wall() or not \$Position2D/FloorRay.is_colliding() and is_on_floor():
direction = direction * -1

if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
``````

amaou310 | 2023-02-11 04:52

Since your enemy won’t be listening to input events from the player, the last two lines that are responsible for starting a jump should be refactored.
Try adding a `Timer` node as a child, and you should run the jump logic when it emits the `timeout` signal.
You’ll still need to check if the monster `is_on_floor()`, if so, you can set the vertical velocity to the jump velocity.

zhyrin | 2023-02-11 10:18

thanks for the further advice.
Yes it did work!

``````func _ready():
#enemy_state = state.IDLE
\$Jump_Timer.start()
pass

func get_gravity() -> float:
return jump_gravity if velocity.y < 0.0 else fall_gravity

func _physics_process(delta):
if velocity.x>0:
\$Position2D.scale.x=1
elif velocity.x<0:
\$Position2D.scale.x=-1

velocity.y += get_gravity() * delta
velocity.x = speed * direction
velocity = move_and_slide(velocity, Vector2.UP)

if is_on_wall() or not \$Position2D/FloorRay.is_colliding() and is_on_floor():
direction = direction * -1

func _on_Timer_timeout():
if is_on_floor():
velocity.y = jump_velocity
print("Do Jump")
\$Jump_Timer.start()
``````

I wanted make it move only while jumping, therefore, I changed speed variable to zero, and added velocity.x = jump_speed * direction. but it does not jump forward as I expected.

``````   func _on_Timer_timeout():
if is_on_floor():
velocity.y = jump_velocity
velocity.x = jump_speed * direction
print("Do Jump")
\$Jump_Timer.start()
``````

amaou310 | 2023-02-11 12:36