I'm so close! I'm using the XNA Game State Management example found here and trying to modify how it handles input so I can delay the key/create an input buffer.
In GameplayScreen.cs I've declared a double called elapsedTime and set it equal to 0.
In the HandleInput method I've changed the Key.Right button press to:
if (keyboardState.IsKeyDown(Keys.Left))
movement.X -= 50;
if (keyboardState.IsKeyDown(Keys.Right))
{
elapsedTime -= gameTime.ElapsedGameTime.TotalMilliseconds;
if (elapsedTime <= 0)
{
movement.X += 50;
elapsedTime = 10;
}
}
else
{
elapsedTime = 0;
}
The pseudo code:
If the right arrow key is not pressed set elapsedTime to 0. If it is pressed, the elapsedTime equals itself minus the milliseconds since the last frame. If the difference then equals 0 or less, move the object 50, and then set the elapsedTime to 10 (the delay).
If the key is being held down elapsedTime should never be set to 0 via the else. Instead, after elapsedTime is set to 10 after a successful check, the elapsedTime should get lower and lower because it's being subtracted by the TotalMilliseconds. When that reaches 0, it successfully passes the check again and moves the object once more.
The pr开发者_开发问答oblem is, it moves the object once per press but doesn't work if you hold it down. Can anyone offer any sort of tip/example/bit of knowledge towards this? Thanks in advance, it's been driving me nuts. In theory I thought this would for sure work.
CLARIFICATION
Think of a grid when your thinking about how I want the block to move. Instead of just fluidly moving across the screen, it's moving by it's width (sorta jumping) to the next position. If I hold down the key, it races across the screen. I want to slow this whole process down so that holding the key creates an X millisecond delay between it 'jumping'/moving by it's width.
EDIT: Turns out gameTime.ElapsedGameTime.TotalMilliseconds is returning 0... all of the time. I have no idea why.
SOLVED: Found out gameTime.ElapsedGameTime.TotalMilliseconds was returning 0... moved it somewhere else.
Found out gameTime.ElapsedGameTime.TotalMilliseconds was returning 0... used the GameTime parameter in the Update method to set a public double variable called GameT. GameT was then used in the HandleInput method and returned the valid times. Not the most legit way to do it, but it works for now.
So the question is, what behavior do you want your entity to have?
- If you want it to move once when you press the button (as if moving through a menu), then you want to store the KeyboardState in a class level variable so that each update you can check it against the current state. You would only move if the button was not held in the previous state, but is held now. That ensures that you will only ever trigger the action once.
- If you want it to move regularly and smoothly (as in, scrolling to the right when you press the right arrow), then scale your movement variable (currently hardcoded to 50) by a certain amount (which you can tune). So something like
movement.X += 50 * .05;
. You can tune it up and down until the movement that it does each frame matches the speed you want it to move
If you're using fixed game time you don't have to delay by time at all. You can keep a variable that tracks "frames" and update based on that:
int elapsedFrames = 10; //<- Set up somewhere higher than the function call
if (keyboardState.IsKeyDown(Keys.Right))
{
elapsedFrames++;
if (elapsedFrames >= 10)
{
movement.X += 50;
elapsedTime = 0;
}
}
else
{
elapsedTime = 10;
}
That way you don't have to deal with gameTime.
精彩评论