C# 在看似无关的代码更改后,按键检测无法工作

C# 在看似无关的代码更改后,按键检测无法工作,c#,xna,keyboard,C#,Xna,Keyboard,我正试图让Enter键为我的游戏生成一个新的“地图”,但无论出于什么原因,在实现全屏后,输入检查将不再起作用。我试着删除新代码,一次只按一个键,但还是不行 以下是检查代码及其使用的方法,以及newMap方法: public class Game1 : Microsoft.Xna.Framework.Game { // ... protected override void Update(GameTime gameTime) { // ...

我正试图让Enter键为我的游戏生成一个新的“地图”,但无论出于什么原因,在实现全屏后,输入检查将不再起作用。我试着删除新代码,一次只按一个键,但还是不行

以下是检查代码及其使用的方法,以及newMap方法:

public class Game1 : Microsoft.Xna.Framework.Game
{
    // ...

    protected override void Update(GameTime gameTime)
    {
        // ...

        // Check if Enter was pressed - if so, generate a new map
        if (CheckInput(Keys.Enter, 1))
        {
            blocks = newMap(map, blocks, console);
        }

        // ...
    }

    // Method: Checks if a key is/was pressed
    public bool CheckInput(Keys key, int checkType)
    {
        // Get current keyboard state
        KeyboardState newState = Keyboard.GetState();
        bool retType = false; // Return type

        if (checkType == 0)
        {
            // Check Type: Is key currently down?
            retType = newState.IsKeyDown(key);
        }
        else if (checkType == 1)
        {
            // Check Type: Was the key pressed?
            if (newState.IsKeyDown(key))
            {
                if (!oldState.IsKeyDown(key))
                {
                    // Key was just pressed
                    retType = true;
                }
                else
                {
                    // Key was already pressed, return false
                    retType = false;
                }
            }
        }

        // Save keyboard state
        oldState = newState;

        // Return result
        return retType;
    }

    // Method: Generate a new map
    public List<Block> newMap(Map map, List<Block> blockList, Console console)
    {
        // Create new map block coordinates
        List<Vector2> positions = new List<Vector2>();
        positions = map.generateMap(console);

        // Clear list and reallocate memory previously used up by it
        blockList.Clear();
        blockList.TrimExcess();

        // Add new blocks to the list using positions created by generateMap()
        foreach (Vector2 pos in positions)
        {
            blockList.Add(new Block() { Position = pos, Texture = dirtTex });
        }

        // Return modified list
        return blockList;
    }

    // ...
}
当我尝试添加要在按下该键时显示的文本时,似乎即使按下了正确的键,If也从未触发


似乎当CheckInput方法尝试检查刚刚按下的“Enter”时,它通过了第一次检查
if(newState.IsKeyDown(key))
(返回true),但第二次检查
if(!oldState.IsKeyDown(key))
失败。(并返回true,但不应返回)

滚动回答,已更新

下面是我编写您的代码的方式:

public class Game1 : Microsoft.Xna.Framework.Game
{
    // ...
    protected override void Update(GameTime gameTime)
    {
        // ...
        // Check if Enter was pressed - if so, generate a new map
        if (CheckInput(Keys.Enter, 1))
        {
            blocks = newMap(map, blocks, console);
        }
        // ...
    }

    // Method: Checks if a key is/was pressed
    public bool CheckInput(Keys key, int checkType)
    { 
        KeyboardState newState = Keyboard.GetState();   // Get current keyboard state
        bool retType = false;                           // Return type

        var debug_new = newState.IsKeyDown(key);
        var debug_old = oldState.IsKeyDown(key);

        if (checkType == 0)         // Check Type: Is key currently down?
        {
            retType = newState.IsKeyDown(key);
        }
        // Should happen only once, if key wasn't pressed before
        else if (checkType == 1 && newState.IsKeyDown(key))    
        {
            // Key pressed, wasn't pressed last update  -> true. 
            // Key pressed, but was pressed last update -> false.
            retType = !oldState.IsKeydown(key); 
        }

        oldState = newState;            // Save keyboard state

        return retType;                 // Return result
    }
    // ...
}
这本书简短易读。
现在,何时/如何从调用更新方法?当你按钥匙时会发生吗?它是循环的吗

接下来,如果您删除(或注释掉)您更改的内容(在第三个代码块中),它是否有效

接下来,如果您在
检查输入中输入一个断点,它是否会在每次按键时停止

希望从那里你能得到更多的帮助

编辑:

好的,让我们看看,您何时/为什么要使用
检查输入(键,0)
调用该方法? 例如,您是否试图避免重复按Enter键?(这些检查有什么意义?)

另一次编辑:
是的,我知道它被称为每一帧,而不是按键。唯一的问题是我不知道有多少次。。。60 fps与5 fps是一个很大的区别。

我想知道它是否有可能不同步。。。我要做的是在那里设置一个条件调试点,在按下并释放
Enter
时中断,并仔细查看您的
newState
/
oldState
,以确保逻辑按照您想要的方式工作(我相信代码越短越好:)

通过在Update方法中添加一行来修复它,而不是依赖CheckInput方法期间更新它

更新的方法:

protected override void Update(GameTime gameTime)
{
    // ...

    if (CheckInput(Keys.Enter, 1))
    {
        blocks = newMap(map, blocks, console);
    }

    oldState = Keyboard.GetState();

    // ...
}

// Method: Checks if a key is/was pressed
public bool CheckInput(Keys key, int checkType)
{
    // Get current keyboard state
    KeyboardState newState = Keyboard.GetState();
    bool retType = false; // Return type

    if (checkType == 0)
    {
        // Check Type: Is key currently down?
        if (newState.IsKeyDown(key))
        {
            retType = true;
        }
        else
        {
            retType = false;
        }
    }
    else if (checkType == 1)
    {
        // Check Type: Was the key pressed?
        if (newState.IsKeyDown(key))
        {
            if (!oldState.IsKeyDown(key))
            {
                // Key was just pressed
                retType = true;
            }
            else
            {
                // Key was already pressed, return false
                retType = false;
            }
        }
    }

    // Return result
    return retType;
}

尽管我不能完全确定这是如何工作的(特别是考虑到它以前没有进行过这种修改),但它仍然是一个解决方案。

首先;它会自动调用每一帧。第二如果我把它们注释掉,一切都不会改变。第三它在那里停止,但似乎通过了第一个“检查”(钥匙当前是否已关闭?),但第二个检查失败,该检查应返回false(钥匙是否已关闭,最后一个检查?),但由于某种原因返回true。我已经为这个问题添加了一些内容。为了回应您的编辑,0方法的用途是用于移动,如果按住按钮,“true”应该能够不断返回。1表示在任何时候,按钮仅应在第一次按下时激活。另外,在代码缩短方面远远领先于您-已经做到了。很容易领先于我,我没有您的代码:)。现在,用更新的代码编辑你的问题怎么样?移除第二个框,这在我看来并不重要,然后我们可能会用按键检测来指出你的问题(假设你在乎,如果不在乎,既然你有你的解决方案,你可以留下它:)完成,完成。尽管有解决方案,但知道问题发生的原因是我非常想知道的有用信息。我已经编辑了您的主代码(要短得多,您不同意吗?)。看看这两个变量,设置断点,让我知道会发生什么。(好的,一旦更新被授权,即:)我看到您的编辑被拒绝,但尽管如此,我已经使用建议的断点测试了代码-它仍然无法工作,但调试变量似乎没有问题。请注意,CheckInput方法是在每一帧调用的,而不是在按键时调用的。
protected override void Update(GameTime gameTime)
{
    // ...

    if (CheckInput(Keys.Enter, 1))
    {
        blocks = newMap(map, blocks, console);
    }

    oldState = Keyboard.GetState();

    // ...
}

// Method: Checks if a key is/was pressed
public bool CheckInput(Keys key, int checkType)
{
    // Get current keyboard state
    KeyboardState newState = Keyboard.GetState();
    bool retType = false; // Return type

    if (checkType == 0)
    {
        // Check Type: Is key currently down?
        if (newState.IsKeyDown(key))
        {
            retType = true;
        }
        else
        {
            retType = false;
        }
    }
    else if (checkType == 1)
    {
        // Check Type: Was the key pressed?
        if (newState.IsKeyDown(key))
        {
            if (!oldState.IsKeyDown(key))
            {
                // Key was just pressed
                retType = true;
            }
            else
            {
                // Key was already pressed, return false
                retType = false;
            }
        }
    }

    // Return result
    return retType;
}