【问题标题】:Textbox in a C# XNA GameC# XNA 游戏中的文本框
【发布时间】:2013-06-26 12:49:19
【问题描述】:

我是 XNA 的新手。我正在制作一个需要关卡编辑器的游戏。我需要一个文本框来获取关卡名称及其描述。所以我写了这样的代码:

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;

但是当我尝试输入一些字母时,它们不会被添加到levelName 字符串中。有人可以帮我解决这个问题吗?

【问题讨论】:

  • 测试了代码,对我来说很好用。另外,我会用经过的时间说,如果按住相同的键,每 200 毫秒添加一个字母,因为键入“lol”会使其显示为“llllloooooooooooollllllllllllll”

标签: c# textbox xna


【解决方案1】:

据我所知,您的代码运行良好。我玩弄了它并添加了一些改进。你不需要一些东西,我做到了,所以当你拿着钥匙时,它不会那么快地发送垃圾邮件。我会添加对其他键(如符号和大写字母)的支持,但它是一个相当长的 switch 语句,因此您可以查看this 文章并轻松实现它。

我添加了更多变量,所有与文本框相关的内容现在都应为

    Keys[] lastKeys;
    KeyboardState lastKeyboardState;

    public double timer;

    public string levelName;

如果需要,您还可以将 currentKeyboardState 变量添加为全局变量。

现在对于代码,我将其拆分为 2 种方法,以防止必须复制代码两次

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;
}

以及重置计时器并实际计算字符串的方法(这是您添加移位和符号等代码的地方)

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;
}

您还可以使用StringBuilder 进行进一步优化。

如果您想继续编写自己的 UI,请继续。我仍然会推荐使用 UI 库(我使用的是新恢复的 Neoforce Controls),但在 here 上会有更大的讨论。

【讨论】:

  • 我在这段代码中有两个相同的错误: System.Array 不包含 Contains 的定义,并且找不到接受 System.Array 类型的第一个参数的扩展方法“Contains”(是您缺少 using 指令或程序集引用?)(在 lastKeys.Contains)
  • 您需要参考 System.Linq,抱歉我忘记了! using System.Linq;
  • 哦,哈哈,我忘记了 linq(我添加了每个 System.Collections):P 谢谢,现在可以使用了。
  • 好的,没问题!我想知道实际的潜在问题是什么......它从我的一开始就一直有效。另外,我记得你来自 EE :)
【解决方案2】:

我建议您使用其中一个 XNA GUI 框架,其中包含表单元素、场景管理器和其他有用的东西。

herethere

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    相关资源
    最近更新 更多