问题
I'm new to XNA. I'm making a game which needs level editor. I need a textbox to get a level name and its description. So I wrote a code like this:
if (isSaveBox)
{
KeyboardState ks = Keyboard.GetState();
Keys[] keys = ks.GetPressedKeys();
Keys tempKey = Keys.None;
foreach (Keys key in keys)
{
Keys currentKey = key;
if (ks.IsKeyUp(lastKey))
{
string toadd = key.ToString();
if (!(key == Keys.None) && key != Keys.Space && key != Keys.Back && key != Keys.Enter)
{
levelName += toadd;
}
else if (key == Keys.Space)
{
levelName += " ";
}
else if (key == Keys.Back)
{
levelName.Remove(levelName.Length - 1);
lastKey = currentKey;
}
}
if (currentKey != Keys.None && ks.IsKeyDown(currentKey))
{
tempKey = currentKey;
}
}
lastKey = tempKey;
message = "Save level" + "\n" + "Enter - yes / Esc - no" + "\n" + levelName;
But when I try to type some letters they won't be added to the levelName
string. Can somebody help me with this?
回答1:
As far as I can tell your code works fine. I played around with it and added some improvements. You didn't need some stuff and I made it so when you hold a key it doesn't spam so fast. I would have added support for other keys like symbols and caps, but it's quite a long switch statement for all that, so you can take a look at this article and implement it easily.
I added a few more variable, all your textbox related stuff should now read as
Keys[] lastKeys;
KeyboardState lastKeyboardState;
public double timer;
public string levelName;
You can also add your currentKeyboardState
variable as a global variable if you want.
Now for the code, I split it into 2 methods to prevent having to copy the code twice
if (isSaveBox)
{
//Get the current keyboard state and keys that are pressed
KeyboardState keyboardState = Keyboard.GetState();
Keys[] keys = keyboardState.GetPressedKeys();
foreach (Keys currentKey in keys)
{
if (currentKey != Keys.None)
{
//If we have pressed the same key twice, wait atleast 125ms before adding it again
if (lastKeys.Contains(currentKey))
{
if ((gameTime.TotalGameTime.TotalMilliseconds - timer > 125))
HandleKey(gameTime, currentKey);
}
//If we press a new key, add it
else if (!lastKeys.Contains(currentKey))
HandleKey(gameTime, currentKey);
}
}
//Save the last keys and pressed keys array
lastKeyboardState = keyboardState;
lastKeys = keys;
}
And the method to reset the timer and actually figure out the strings (this is where you would add code for shift and symbols, etc)
private void HandleKey(GameTime gameTime, Keys currentKey)
{
string keyString = currentKey.ToString();
if (currentKey == Keys.Space)
levelName += " ";
else if ((currentKey == Keys.Back || currentKey == Keys.Delete) && levelName.Length > 0)
levelName = levelName.Remove(levelName.Length - 1);
else if (currentKey == Keys.Enter)
return;
else
levelName += keyString;
//Set the timer to the current time
timer = gameTime.TotalGameTime.TotalMilliseconds;
}
You could also use a StringBuilder
for further optimization.
If you want to continue writing your own UI, go ahead. I still would recommend using a UI library (I use the newly revived Neoforce Controls) but there is a larger discussion for that over here.
回答2:
I recommend you use one of a XNA GUI frameworks, that contain form elements, scene managers an other useful things.
Look here or there
来源:https://stackoverflow.com/questions/17320500/textbox-in-a-c-sharp-xna-game