1
\$\begingroup\$

I'm using LWJGL to develop a 3D game.

I'm having trouble with my keyboard handler. My aim is to implement the function which is holding Space then release it to trigger an increasing of the velocity and height of the main character within an interval of time (the longer you hold, the more powerful the bounce).

The point is, I want to increase the acceleration in Keyboard.isRepeatEvent() but, in this condition, the interval between 2 frames is nearly 0, so I can't increase the acceleration. It seems like this event is calculated in 1 frame so now I couldn't think out a new method. This my code:

Keyboard.enableRepeatEvents(true);

    while(Keyboard.next())
    {
        if(Keyboard.getEventKey() == Keyboard.KEY_SPACE)
            if(Keyboard.getEventKeyState())
            {
                if(Keyboard.isRepeatEvent())
                {
                    while(test <= 200)
                    {
                         test += getDelta() / 1000;
                         System.out.println("test Value ---- " + test);
                    }
                }
                // Key held down
                else {

                }
                // Key pressed
            }
            else
                System.out.println("test ------------------- " + test);
        // Key released
    }

getDelta() gets the interval between 2 frames.

\$\endgroup\$
  • \$\begingroup\$ You should use an up to date LWJGL version. LWJGL 3 is a couple years old now. \$\endgroup\$ – Bálint Oct 5 '16 at 13:24
1
\$\begingroup\$

Why not get the system time upon the 1st detection of the event, then get the system time when the event is no longer detected (i.e. "button up")? This interval could then be used to calculate the acceleration.

Ergo (using your code):

((Disclaimer: I don't program in java so please forgive any syntax issues. I'm aiming for java-esque psuedocode.))

Keyboard.enableRepeatEvents(true);
long timeI; //timestamp when button is hit
long timeF; //timestamp when button is released
long deltaT; //time period between timeF and timeI
while(Keyboard.next())
{
    if(Keyboard.getEventKey() == Keyboard.KEY_SPACE)
        if(Keyboard.getEventKeyState())
        {
            //setTimeI if it hasn't been set yet.
            if (timeI == 0)
            {
                timeI = System.currentTimeMillis();
            }
            if(Keyboard.isRepeatEvent())
            {
                while(test <= 200)
                {
                     test += getDelta() / 1000;
                     System.out.println("test Value ---- " + test);
                }
            }
            // Key held down
            else {

            }
            // Key pressed
        }
        else 
        {
            //setTimeF if timeI hasn't been set 
            //and if the button is not pressed (ergo released)
            if(timeI > 0)
            {
                timeF = System.currentTimeMillis();
                deltaT = timeF - timeI;
                timeI = 0; //reset initial time
            }
            System.out.println("test ------------------- " + test);
    // Key released
}
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

You should not use a while loop to fetch keyboard events, instead, find a way to fetch keyboard events with a lower, less variable complexity.

However, to answser your question:

//fetch your key events
...
//setup
final double maxSpaceHoldTimeInSeconds = 2.;
final Vector3 maxVelocity = ..; //max velocity after keyboard is released.

//apply your space-bar logic

//if the keyboard is PRESSED
if ( Keyboard.getEventKey() == Keyboard.KEY_SPACE && Keyboard.getAction() ==         Keyboard.ACTION_PRESSED ) {
    spaceBarTimer = 0.;
}

//if the keyboard is not yet RELEASED
else if ( Keyboard.getEventKey() == Keyboard.KEY_SPACE && Keyboard.getAction() != Keyboard.ACTION_RELEASED ) {
    if ( spaceBarTimer > maxSpaceHoldTimeInSeconds ) {
        //some logic to stop the player from holding their spacebar for too long.
        return;
    }

    spaceBarTimer += getDelta();
    //the delta counts the time between frames as you have already stated.
    //what this means is if your gameloop is setup for a 60fps game loop
    //then your delta == 1/60
}

//if the keyboard is RELEASED
else if ( Keyboard.getEventKey() == Keyboard.KEY_SPACE && Keyboard.getAction() == Keyboard.ACTION_RELEASED ) {
    player.addVelocity(maxVelocity.multiplyWithDouble( maxSpaceHoldTimeInSeconds / spaceBarTimer ));
}

Of course, this will increase velocity in a linear fashion, if you want your player to experience an exponential increase of velocity when holding their keyboard for longer, then you need to modify the player.addVelocity() line, something like this maybe.

player.addVelocity(maxVelocity.multiplyWithDouble( maxSpaceHoldTimeInSeconds / Math.min(maxSpaceHoldTimeInSeconds, spaceBarTimer * spaceBarTimer) ));
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.