0 votes

Hello! So I'm trying to implement cayote time for my player in my 2d platformer game. One of the requirements is to check if the player is in midair by checking it using !isonfloor. However, regardless if the player is in the air or not, the boolean still returns true and it's driving me nuts. I've already supplied the UP Vector for moveandslide so in theory, it should detect it. Here is the code for Player.gd:

extends KinematicBody2D

var motion = Vector2.ZERO

export var ACCELERATION = 1750
const SPEED = 350
const MAXSPEED = 600
const MAX_FALL = 160
const GRAVITY = 2000
const JUMP_FORCE = -700

onready var spawnPoint = get_parent().get_node("SpawnPoint")
onready var currentSpawn = spawnPoint.position

# TODO: Make State Machines

var health : int = 3
var maxHealth : int = 3
var current_hold_time = 0
var jump_hold_time = 0.2
var hasHitSomething = false
var hasReachedEnd : bool = false
var canJumpMidAir : bool = false

# TODO
var isWaterLevel : bool = false

signal health_changed(player_hearts)
signal levelComplete()
signal died()

onready var animation = $Sprite

func _ready():
    connect("health_changed", get_parent().find_node("HUD"), "_on_health_changed")
    connect("levelComplete", get_parent().find_node("HUD"), "_on_level_complete")

    emit_signal("health_changed", health)

    Global.player = self
    position = spawnPoint.position

func _exit_tree():
    # I forgor what this does
    Global.player = null

func _physics_process(delta) -> void:
    var direction : int = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
    var jumping : bool = Input.is_action_pressed("jump")

    #Do physics while level hasn't finished yet
    if !Global.levelFinished:

        # Jumping
        if jumping && is_on_floor() && canJumpMidAir:
            $jump.play()
            motion.y = JUMP_FORCE
            current_hold_time = jump_hold_time
        elif !is_on_floor():
            enableCayoteTime()

        #while on air
        elif current_hold_time > 0:
            if jumping:
                # then keep jumping
                motion.y = JUMP_FORCE
            else:
                current_hold_time = 0

        # Subtract every frame
        current_hold_time -= delta

        if direction > 0:
            animation.flip_h = false
        elif direction < 0:
            animation.flip_h = true

        if is_on_floor():
            # set up cayote time
            canJumpMidAir = true

            if direction != 0:
                animation.play("walk")
            else:
                animation.play("idle")
        elif jumping or hasHitSomething:
            animation.play("jump")


        if direction != 0:
            motion.x += direction * ACCELERATION * delta
            motion.x = clamp(motion.x, -MAXSPEED, MAXSPEED)
        else:
            motion.x = lerp(motion.x, 0, 0.125)

        motion.y += GRAVITY * delta

        #2nd paramater is the up direction; you need it or otherwise is_on_floor method won't work.
        motion = move_and_slide(motion, Vector2.UP)

        if(position.y > 750) or health <= 0:
            $respawn.play()
            health = 3
            backToSpawn()
    else:
        # TODO -> if level finished, make him decelerate, play victory and jump a few times
        $Sprite.play("idle")
        motion.x = lerp(motion.x, 0, 0.05)
        motion.y += GRAVITY * delta

func enableCayoteTime() -> void:
    #currently activates every frame
    print("cayote time active")
    yield(get_tree().create_timer(.1), "timeout")
    canJumpMidAir = false

func bounce() -> void:
    hasHitSomething = true
    motion.y = JUMP_FORCE * .8
    hasHitSomething = false

func bounceDirection(direction) -> void:
    hasHitSomething = true
    motion.y = JUMP_FORCE * .90
    motion.x = direction * 700
    hasHitSomething = false

func flashWhenHit() -> void:
    modulate = Color(255, 145, 145)
    yield(get_tree().create_timer(.3), "timeout")
    modulate = Color(1, 1, 1)

func damage() -> void:
    if health != 0:
        $hurt.play()
        flashWhenHit()
        health -= 1
        emit_signal("health_changed", health)
    else:
        backToSpawn()

func backToSpawn() -> void:
    emit_signal("health_changed", health)
    position = currentSpawn

    motion.x = 0

func _on_checkpoint(newSpawnPoint) -> void:
    currentSpawn = newSpawnPoint

func _on_one_up() -> void:
    print(health)
    health += 1
    emit_signal("health_changed", health)
    $OneUp.play()

func levelComplete() -> void:
    emit_signal("levelComplete")
    for member in get_tree().get_nodes_in_group("music"):
        member.stop()   
    yield(get_tree().create_timer(.2), "timeout")
    $win.play()

Does anyone know what seems to be the problem? Thanks!

Godot version v3.4 stable
in Engine by (20 points)
edited by

1 Answer

+1 vote
Best answer

Are you sure it is always showing as true or is it possible you are assuming that because enableCayoteTime() doesnt get activated?

You have the following code

elif !is_on_floor():
    enableCayoteTime()

and I think you need to change this too

    elif not is_on_floor():
        enableCayoteTime()
by (2,139 points)
selected by

I've put a print statement inside cayote time and indeed, I can confirm that it's active as it prints uninterruptedly when the game starts. Also is there any difference between not and "!"? They seem all same to me

Both "not" and "!" mean not but my understanding is they apply in different circumstances. ! applies to applications of equals for example you could write

elif is_on_floor() != True:

which would mean the same thing as

elif not is_on_floor():

When you write

elif !is_on_floor(): 

the system isnt looking for the same string, it applies the ! to the rest of the string so it is looking for a function called

!is_on_floor 

rather than

is_on_floor

does that make sense?

Thanks for the explanation! I'll take note of this. Also figured out the character starts midair which explains the print logs, and realized it wasn't endless when I pressed jump and saw the scroll bar only shrinking during the jump duration. It's likely the fault of how the cayote time function is set up, but isn't part of my post's question so I guess I'll pick your explanation for now

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.