0

我试图让 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;
    }

    // ...
}

当它坏了时,我从来没有碰过上面的任何代码——改变键似乎无法修复它。尽管如此,我还是在另一个使用 WASD 且运行良好的 Game1 方法中设置了相机移动。我所做的只是在这里添加几行代码:

private int BackBufferWidth = 1280; // Added these variables
private int BackBufferHeight = 800;

public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    graphics.PreferredBackBufferWidth = BackBufferWidth; // and this
    graphics.PreferredBackBufferHeight = BackBufferHeight; // this
    Content.RootDirectory = "Content";

    this.graphics.IsFullScreen = true; // and this
}

当我尝试添加要在按下键时显示的文本时,尽管按下了正确的键,但似乎从未触发 If 。

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

4

2 回答 2

1

滚动答案,更新

这是我编写代码的方式:

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
    }
    // ...
}

它更短,更容易阅读。


现在,何时/如何调用您的更新方法?当你按下一个键时会发生这种情况吗?它在一个循环中吗?

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

接下来,如果你在你的 中设置一个断点CheckInput,它会在你每次击键时停在那里吗?

希望从那里您将能够获得更多帮助。

编辑:

好的,让我们看看,您何时/为什么要使用 a 调用该方法CheckInput(key, 0)?例如,您是否试图避免双击 Enter?(这些检查有什么意义?)

另一个编辑:
是的,我知道它被称为每一帧而不是按键。唯一的问题是我不知道那是多久...... 60 fps 与 5 fps 是一个很大的区别。
想知道它是否有可能以某种方式不同步......我会做的是在那里设置一个条件调试点,在Enter按下时中断,释放,并好好看看你的newState/ oldState,以确保逻辑有效你想要的方式(我相信更短的代码更容易:)

于 2013-11-05T03:57:57.447 回答
0

通过在 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;
}

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

于 2013-11-05T04:45:35.283 回答