move_and_slide and is_on_floor problems

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

Hi:
I have the next scrpit for my player:

extends KinematicBody2D

var speed = 20
var jump_speed = -30
var velocity = Vector2()
var grav = 98

func _ready():
	$AnimatedSprite.play()
func _input(event):
	if event.is_action_pressed("ui_up") and is_on_floor():
		velocity.y = jump_speed

func _process(delta):
	velocity.x = 0
	if Input.is_action_pressed("ui_right"):
		velocity.x += speed
	if Input.is_action_pressed("ui_left"):
		velocity.x -= speed
	if velocity.length() > 0:
		if velocity.x < 0:
			$AnimatedSprite.flip_v = true
			$AnimatedSprite.rotation_degrees = 180 
		elif velocity.x > 0:
			$AnimatedSprite.flip_v = false
			$AnimatedSprite.rotation_degrees = 0 			
		if is_on_floor():
			if velocity.x == 0:
				$AnimatedSprite.animation = "idle"
			else:
				$AnimatedSprite.animation = "moving"
		else:
			$AnimatedSprite.animation = "jumping"
			
	if (!is_on_floor()):
		velocity.y += grav * delta
	velocity = move_and_slide(velocity, Vector2(0,-1))

However, this is not working. For some reason, when velocity.y gets updated to 0 in move_and_slide, is_on_floor no longer returns true, preventing me to jump or change animation. I tryed doing it on _physics_process but it works worse (very slow, and also does not detect is_on_floor).

I read something about a safe_margin, but i cannot figure out how to set that property… any help?

:bust_in_silhouette: Reply From: p7f

Hi, i solved this by moving some code to _physics_process(). This is the code if someone needs it:

    extends KinematicBody2D

    var Bullet = preload("res://Bullet.tscn")

    var speed = 200
    var jump_speed = -350
    var shot_speed = 100
    var velocity = Vector2()
    var grav = 980
    var shooting = false

    func _ready():
    	$AnimatedSprite.play()
    	$AnimatedSprite.connect("animation_finished",self,"on_animation_finished")
    func _input(event):
    	if event.is_action_pressed("ui_up") and is_on_floor():
    		velocity.y = jump_speed
    	if event.is_action_pressed("shoot") and !shooting:
    		shooting = true
    		shot_speed = 20
    		velocity.y = -200
    		fire_weapon()
    
    func _physics_process(delta):
    	velocity.x = 0
    	if Input.is_action_pressed("ui_right"):
    		velocity.x += speed
    	if Input.is_action_pressed("ui_left"):
    		velocity.x -= speed
    	if velocity.length() > 0:
    		if velocity.x < 0:
    			$AnimatedSprite.flip_v = true
    			$AnimatedSprite.rotation_degrees = 180 
    		elif velocity.x > 0:
    			$AnimatedSprite.flip_v = false
    			$AnimatedSprite.rotation_degrees = 0 
    	if shooting:
    		$AnimatedSprite.animation = "shot"
    		velocity.x = -shot_speed * cos($AnimatedSprite.rotation_degrees)
    		shot_speed *= 0.98
    	else:
    		if is_on_floor():
    			if velocity.x == 0:
    				$AnimatedSprite.animation = "idle"
    			else:
    				$AnimatedSprite.animation = "moving"
    		else:
    			$AnimatedSprite.animation = "jumping"
    	
    	velocity.y += grav * delta
    	velocity = move_and_slide(velocity, Vector2(0,-1))
    
    func on_animation_finished():
    	if $AnimatedSprite.animation == "shot":
    		shooting = false
    
    func hit(damage):
    	queue_free()
    
    func fire_weapon():
    	var bullet = Bullet.instance()
    	get_parent().add_child(bullet)
    	if $AnimatedSprite.flip_v :
    		bullet.position = $ShotLeft.global_position
    	else:
    		bullet.position = $ShotRight.global_position
    	bullet.rotation_degrees = $AnimatedSprite.rotation_degrees
    	bullet.speed = Vector2(1500 * cos(bullet.rotation),1500*sin(bullet.rotation))