This site requires JavaScript, please enable it in your browser!
Greenfoot back
ShadowJL
ShadowJL wrote ...

2021/5/6

isKeyDown workaround?

ShadowJL ShadowJL

2021/5/6

#
Hello, I am having a bit of an issue with the isKeyDown command. It obviously detects if a key is being held, however I want to make it stop detecting at a certain point. Here's my code:
public void jump()
    {
        if (Greenfoot.isKeyDown("space") && onBlock())
        {
            vSpeed = jumpStrength;
            fall();
            canHitOrb = 0;
        }
        else if (Greenfoot.isKeyDown("space") && onGround())
        {
            vSpeed = jumpStrength;
            fall();
            canHitOrb = 0;
        }
        else if (Greenfoot.isKeyDown("space") && !onBlock())
        {
            canHitOrb = 1;
        }
        else if (Greenfoot.isKeyDown("space") && !onGround())
        {
            canHitOrb = 1;
        }
        else
        {
            canHitOrb = 0;
        }
    }
I would like the canHitOrb integer to stay as 0 unless the player hits the space bar in midair, in which case it will change to 1 (by the way, my old account is CreatorMoon and yes, this is for my Greenfoot Geometry Dash recreation). If onBlock and onGround (both of them being booleans) are true, the player is not in midair, and vice versa for when they are false. The issue that I have here is that no matter the conditions, as long as the space bar is being held, canHitOrb is equal 1 (on release it becomes 0). Any help would be appreciated. I'd be happy to provide my full player code if it would help.
danpost danpost

2021/5/6

#
ShadowJL wrote...
Hello, I am having a bit of an issue with the isKeyDown command. It obviously detects if a key is being held, however I want to make it stop detecting at a certain point.
You want to detect when the key is initially pressed and when released. You need a boolean field to track the state of the key -- so you can detect the moment the key is pressed and released. Basics include:
// field
private boolean spaceIsDown;

// action code
if (spaceIsDown != Greenfoot.isKeyDown("space")) // state change?
{
    spaceIsDown = !spaceIsDown; // new state
    if (spaceIsDown) // down now?
    {
        if (onGround() || onBlock()) // on surface?
        {
            vSpeed = jumpStrength;
            fall();
            canHitOrb = 0;
        }
        else canHitOrb = 1; // in mid-air
    }
    else canHitOrb = 0; // up now
}
else if (canHitOrb == 1 && (onGround() || onBlock())) canHitOrb = 0;
The last line is for when landing with the key still pressed.
ShadowJL ShadowJL

2021/5/7

#
That seems to work fine. I've edited it a bit so that it fits into my program, however something has occurred with the blue orbs as a result of it. Here's my full player code:
import greenfoot.*;
public class Cube extends Actor
{
    int direction = 6;
    int vSpeed;
    int acceleration = 1;
    int jumpStrength = -11;
    int spaceTimer;
    private boolean spaceIsDown;
    public void act()
    {
        checkKeys();
        checkFall();
        jump();
        die();
        orbJump();
        setLocation(getX()+direction,getY());
        getWorld().showText("Timer: "+spaceTimer, 50, 50);
    }
    public void die()
    {
        
    }
    public void checkKeys()
    {
        if(Greenfoot.isKeyDown("space"))
        {
            jump();
        }
    }
    public void jump()
    {
        if (spaceIsDown != Greenfoot.isKeyDown("space"))
        {
            spaceIsDown = !spaceIsDown;
            if (spaceIsDown)
            {
                if (onGround() || onBlock())
                {
                    vSpeed = jumpStrength;
                    fall();
                    spaceTimer = 0;
                }
                else
                {
                    spaceTimer = 1;
                }
            }
            else
            {
                spaceTimer = 0;
            }
        }
        else if (spaceIsDown && onGround() || onBlock())
        {
            spaceTimer = 0;
            vSpeed = jumpStrength;
            fall();
        }
    }
    public void orbJump()
    {
        if (spaceTimer == 1)
        {
            blueOrb();
            yellowOrb();
        }
    }
    public void yellowOrb()
    {
        if (spaceIsDown && isTouching(YellowOrbActivator.class))
        {
            removeTouching(YellowOrbActivator.class);
            vSpeed = jumpStrength;
            fall();
        }
    }
    public void blueOrb()
    {
        if (spaceIsDown && spaceTimer == 1 && isTouching(BlueOrbActivator.class))
        {
            removeTouching(BlueOrbActivator.class);
            vSpeed = jumpStrength;
            acceleration = -acceleration;
            fall();
            spaceTimer = -1;
        }
        else if (spaceIsDown && spaceTimer == -1 && isTouching(BlueOrbActivator.class))
        {
            removeTouching(BlueOrbActivator.class);
            vSpeed = -jumpStrength;
            acceleration = -acceleration;
            fall();
            spaceTimer = 0;
        }
        if (isTouching(BlueOrbActivator.class) && spaceTimer > -1)
        {
            spaceTimer = 1;
        }
    }
    public void fall()
    {
        setLocation(getX(), getY()+vSpeed);
        vSpeed = vSpeed + acceleration;
        turn(4);
    }
    public boolean onBlock()
    {
        Actor block = getOneObjectAtOffset (0, getImage().getHeight()/2, Block.class);
        return block != null;
    }
    public boolean onGround()
    {
        Actor ground = getOneObjectAtOffset (0, getImage().getHeight()/2, Ground.class);
        return ground != null;
    }
    public void checkFall()
    {
        if (onBlock())
        {
            locationBlock();
            vSpeed = 0;
            setRotation(0);
        }
        else if (onGround())
        {
            locationGround();
            vSpeed = 0;
            setRotation(0);
        }
        else
        {
            fall();
        }
    }
    public void locationBlock()
    {
        Actor objBlock = getOneIntersectingObject(null);
        if ((objBlock != null) && (objBlock instanceof Block))
        {
            int myHeight = getImage().getHeight();
            int objBlockHeight = objBlock.getImage().getHeight();
            int objBlockY = objBlock.getY();
            int dy = (int)Math.signum(vSpeed);
            setLocation(getX(), objBlockY-dy*(objBlockHeight+myHeight)/2);
            vSpeed = 0;
        }
    }
    public void locationGround()
    {
        Actor objGround = getOneIntersectingObject(null);
        if ((objGround != null) && (objGround instanceof Ground))
        {
            int myHeight = getImage().getHeight();
            int objGroundHeight = objGround.getImage().getHeight();
            int objGroundY = objGround.getY();
            int dy = (int)Math.signum(vSpeed);
            setLocation(getX(), objGroundY-dy*(objGroundHeight+myHeight)/2);
            vSpeed = 0;
        }
    }
}
The blueOrb void is the one in question. When I use a blue orb while at normal gravity (spaceTimer equalling 1) my player will flip gravity perfectly fine, however when I use a blue orb while my gravity is flipped (spaceTimer equalling -1) my player will flip gravity but also jump in midair. I'm not sure what I've done wrong here, nor am I sure how to fix it.
ShadowJL ShadowJL

2021/5/7

#
Additionally, my player is auto-jumping when it lands on a block. Not sure how this one happened either, considering it doesn't auto-jump on the ground.
danpost danpost

2021/5/7

#
Line 54 was not implemented as given.
ShadowJL ShadowJL

2021/5/7

#
Thanks, jumping works fine now.
You need to login to post a reply.