我尝试使用XNA的GamePadStates将用户的最新控制器输入存储在队列中。我尝试这样做的方法是将GamePadState放在当前帧中,将其与前一帧中的状态进行比较,将所有按钮和拇指操纵杆输入转换为字符,并将其全部添加到队列中。稍后,我检查队列中最近的输入是什么,并相应地更新游戏状态。当队列过满时,最早的输入将被删除。
但是,我遇到了输入拇指操纵杆的问题。我尝试以与按钮按下类似的方式处理每个方向输入,将其转换为字符,然后将其添加到队列中。这方面的一个例子是
if(newGamePadState.ThumbSticks.Left.X > thumbStickDeadZone &&
oldGamePadState.ThumbSticks.Left.X < thumbStickDeadZone &&
newGamePadState.ThumbSticks.Left.Y > -1.0f * thumbStickDeadZone &&
newGamePadState.ThumbSticks.Left.Y < thumbStickDeadZone)
{
inputQueue.Add('9'); // 9 in this case is the character representation of "Right"
}
正如你所看到的,这种逻辑非常混乱,并且非常快速失控,尤其是在引入检查序数方向时。
有没有更好的方法来正确地写这种东西而不会导致输入重复如果拇指杆上的方向被保持?我最接近解决方案的是检查添加到队列中的最后一组输入是否有任何重复项并将其删除,如果用户在两个单独的输入上按两次相同的方向,则会导致问题。
*注: 作为程序的要求,最近的输入有存储,因为程序最终将能够检查是否已输入某些命令序列。
答案 0 :(得分:0)
我假设你的拇指操纵杆有两个状态“中性”和“方向”。
所以,你的逻辑应该是这样的(警告,很多伪代码):
bool thumbstickActive = false;
void CheckInput()
{
//Pseudo-code, fix to match how you are getting the position
Vector2 currentPostiion = thumbstick1.Position;
if (ThumbstickInDeadZone(currentPosition))
{
thumbStickActive = false;
}
else if (!thumbStickActive)
{
ActionQueue.Enqueue(GetDirection(currentPosition));
thumbStickActive = true;
}
}
基本上,当操纵杆返回“空档”时设置一个标志,如果我们从中立来,则只向队列添加操作。如果您只想说“不是最后一个方向”,请将其更改为:
Direction lastDirection = Direction.None; //Pseudo-enum
void CheckInput()
{
//Pseudo-code, fix to match how you are getting the position
Vector2 currentPostiion = thumbstick1.Position;
Direction currentDirection = GetDirection(currentPosition);
//If GetDirection returns Direction.None for neutral,
//The old check doesn't matter.
if (currentDirection != lastDirection)
{
ActionQueue.Enqueue(currentDirection);
lastDirection = currentDirection;
}
}
仍然是同样的想法,设置存储“最后”状态的变量,并检查该状态是否已经足够改变,以便您想要排除操作。
它有两个你应该已经拥有的辅助函数。如果拇指操纵杆处于中间位置,则第一个(ThumbstickInDeadZone
)返回true
,否则返回false
。第二个(GetDirection
)返回由拇指操纵杆的当前位置表示的方向。