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