XNA tile based movement [closed]
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
开发者_JAVA百科Closed 4 years ago.
Improve this questionI am trying to make a 2D tile-based top-down game in XNA. It is 16 x 16 tiles, and each tile is 25 pixels.
I have a character sprite starting at (0, 0) first tile, and I'm trying to make it movable using the keyboard from tile to tile. So in the Update method, when the arrow key is pressed, I tried adding or subtracting 25 to x or y of the position vector. It seems to be aligned in the tiles when moving, but it's moving about 4-5 tiles instead of just 1 tile at a time. I have tried multiplying it with gameTime.TotalGameTime.TotalSeconds, but it doesn't seem to help.
I'm kind of new to using XNA. Does anyone have any tutorials or can help with how to calculate the movement? Thanks in advance.
If you just check IsKeyDown
every frame, it will say it is down on each frame that it is held down. At 60 frames-per-second, pressing a key will result in it being in the down state for several frames. Hence on each frame you are moving your character! By the time you let go of the key - he'll have moved several squares.
If you want to detect each key press (the key entering the "down" state), you need something like this:
KeyboardState keyboardState, lastKeyboardState;
bool KeyPressed(Keys key)
{
return keyboardState.IsKeyDown(key) && lastKeyboardState.IsKeyUp(key);
}
override void Update(GameTime gameTime)
{
lastKeyboardState = keyboardState;
keyboardState = Keyboard.GetState();
if(KeyPressed(Keys.Right)) { /* do stuff... */ }
}
However if you want to add a "repeat" effect when holding down the key (like what happens in typing), you need to count the time - something like this:
float keyRepeatTime;
const float keyRepeatDelay = 0.5f; // repeat rate
override void Update(GameTime gameTime)
{
lastKeyboardState = keyboardState;
keyboardState = Keyboard.GetState();
float seconds = (float)gameTime.ElapsedGameTime.TotalSeconds;
if(keyboardState.IsKeyDown(Keys.Right))
{
if(lastKeyboardState.IsKeyUp(Keys.Right) || keyRepeatTime < 0)
{
keyRepeatTime = keyRepeatDelay;
// do stuff...
}
else
keyRepeatTime -= seconds;
}
}
When you use IsKeyDown, you don't have to use timers.
public void HandleInput(KeyboardState keyState)
{
if (keyState.IsKeyDown(Keys.Left))
{
//go left...
}
}
精彩评论