but that doesn’t seem to work. I would really like one keypress and one increment and then wait for another keypress. What’s the correct method for reading the keyboard presses without ‘rapid fire’?
Not sure if it’s the correct method or if it will help for your use case, but I’ve used a timer that uses the gameTime to pause the player from switching their fighting stance too rapidly in my game if they were to hold down the key that triggers it.
Your code increments the value with each evaluation, as long as the button is pressed.
And this evaluation occurs every frame in your update loop!
To overcome this, I always declare few keyboard states:
a current_keys state, and a past_keys state…
at the BEGINNING of each update cycle, I set the past_keys = present_keys,
and THEN set present_keys from keyboard.getstate…
Then to respond to a button press, you use
if (current_keys.iskeydown(keys.right) && past_keys.iskeyUP(keys.right))
{
This way the button triggering something, depends on the buttons PREVIOUS state too, not just the present one. which is cool.
}
I guess I misunderstood the problem! -But I’d still use my solution, and just NOT evaluate past-key for this instance of button state evaluation, and just also have a timer.
I consider it good practice, and it’s what I do. For keys, mouse and gamepad.
Shooting just relies on a rate of fire timer, but jumping I require an actual re-press of the button, so you don’t just re-jump when hitting a new floor, because you are still holding the button coming off a long-jump.
I really don’t care if I have to repeatedly press the keys or hold them down… I just wanted to get rid of ‘rapid fire’. This is what I ended up with (and setting oldState to newState at the bottom of Update(). This works fine for my purpose (requires repeated key press to scroll):
if (newState.IsKeyDown(Keys.Left) && oldState.IsKeyUp(Keys.Left))
{
if(RewindTimeIndex > 0)
RewindTimeIndex--;
}
if (newState.IsKeyDown(Keys.Right) && oldState.IsKeyUp(Keys.Right))
{
if (RewindTimeIndex < RewindTimeFilePaths.Count() - 1)
RewindTimeIndex++;
}
To slow this down use a float adjustment instead of integer increment or decrement.
To allow a slowdown while the key is pressed, mirror the RewindTimeIndex as a float value to allow changes smaller than 1 per step.
The following code is appropriate for fixed time step at 1/20th(.05) of the original speed. Adjust as needed.
For an unbounded framerate, replace SCROLLSPEED with a scaling of gameTime.ElapsedTime.Seconds
// Class Variables
private float RewindTimeFloat; // initialize to match RewindTimeIndex
private const float SCROLLSPEED = .05f; // for fixed speed or based on elapsed seconds
//
if (newState.IsKeyDown(Keys.Left) )
{
RewindTimeFloat -= SCROLLSPEED;
RewindTimeIndex = (int) RewindTimeFloat;
if(RewindTimeFloat < 0)
RewindTimeFloat = 0;
}
if (newState.IsKeyDown(Keys.Right))
{
if (RewindTimeIndex < RewindTimeFilePaths.Count() - 1 - SCROLLSPEED)
{
RewindTimeFloat += SCROLLSPEED;
RewindTimeIndex = (int) RewindTimeFloat;
}
}