Topic was automatically imported from the old Question2Answer platform.
Asked By
amaou310
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
func _ready():
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()
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()