首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >战斗游戏与输入缓冲

战斗游戏与输入缓冲
EN

Game Development用户
提问于 2012-11-13 10:52:44
回答 2查看 10.3K关注 0票数 7

在战斗游戏中,有一个重要的东西叫做输入缓冲。当您的角色正在执行某个操作时,您可以输入下一个动作,以便尽快激活(缓冲区为5-10帧)。

有没有人已经实现了,或者知道最有效的方法来做到这一点?

我想到了这样的事情:

代码语言:javascript
运行
复制
Enum list moves (a list of all my moves)
if (moves = fireball)
{
    if (Mycharacterisidle)
    {
         Do the fireball
    }
    else if (MycharacterisMoving)
    {
         if (lastspriteisnotfinished)
         {
             InputBuffer++;
         }
         else if(spriteisfinished && InputBuffer < 5)
         {
             Do the fireball
         }
    }
}

有更好的主意吗?谢谢。

EN

回答 2

Game Development用户

发布于 2012-11-13 11:40:40

你用Queue怎么样?

您可以使用Queue<T>的4个重要成员:

  1. Queue.Enqueue(T item) --将您的项目放在队列的末尾。
  2. T Queue.Peek() -查看第一项而不删除它。
  3. T Queue.Dequeue() -获取并删除第一项。
  4. Queue.Count -检查队列中有多少项。

示例使用

以下是表示移动的类:

代码语言:javascript
运行
复制
public enum MoveType
{
    Fireball, Jump, Block
}

public class Move
{
    public MoveType MoveType { get; private set; }
    public double Duration { get; private set; }
    //...

    public Move(MoveType moveType)
    {
        this.MoveType = moveType;
        switch (moveType)
        {
            case MoveType.Fireball:
                this.Duration = 1.0;
                break;
            case MoveType.Block:
                this.Duration = 0.5;
                break;
            case MoveType.Jump:
                this.Duration = 0.8;
                break;
        }
    }
}

您的更新检查是否经过移动:

代码语言:javascript
运行
复制
Queue<Move> _moveQueue = new Queue<Move>();
double _elapsedMoveTime = 0;

public override void Update(GameTime gameTime)
{
    if (_moveQueue.Count > 0)
    {
        _elapsedMoveTime += gameTime.ElapsedGameTime.TotalSeconds;
        Move current = _moveQueue.Peek();
        if (_elapsedMoveTime > current.Duration)
        {
            _elapsedMoveTime -= current.Duration;
            _moveQueue.Dequeue();
        }
    }
    else
    {
        _elapsedMoveTime = 0;
    }
}

要将移动添加到队列中,只需调用

代码语言:javascript
运行
复制
_moveQueue.Enqueue(new Move(MoveType.Fireball));

要得到当前的移动,只需

代码语言:javascript
运行
复制
Move currentMove = _moveQueue.Peek();
if(currentMove.MoveType == MoveType.Fireball)
   //...

另外-不要计算帧中的持续时间,以秒为单位来计数它(如果必须的话,也不要计算毫秒)。

票数 10
EN

Game Development用户

发布于 2013-12-31 20:09:44

我有一个非常简单的方法来检测特殊的移动序列为我的游戏无畏之夜。

它只存储最后60帧输入,但您可以使它任意长度。我实现了一个检查序列是否已经执行的简单方法。它是用Lua写的,但我会尽力用C#为您编写它。

我们使用整数值来表示基于键盘数字垫的方向,但是您可以使用任何类似的方法来替换输入状态。我在这里简化了一些事情,比如在越过对手时不考虑角色的方向翻转。通常情况下,这会为一个特殊的移动输入翻转前后方向。

该算法只需检查输入缓冲区内的CurrentTick偏移量中的每个输入状态,直到maxDuration为止。这假设buffer数组是循环的。

代码语言:javascript
运行
复制
public class Input {
    int bufferSize = 60;
    int[] buffer = new int[60];

    // Offset for the current input in the buffer.
    int CurrentTick = 0;
    ...
    // maxDuration must be <= bufferSize
    public bool CheckSequence(int[] sequence, int maxDuration) {
        int w = sequence.Length-1;

        for(int i=0; i<maxDuration; ++i) {
            int direction = buffer[(CurrentTick-i+bufferSize) % bufferSize];

            if(direction == sequence[w]) 
                --w;
            if(w == -1) 
                return true;
        }

        return false;
    }
}

你可以这样使用它

代码语言:javascript
运行
复制
// Somewhere at the start of the "match"
Input input;
...
// 2=down, 3 = down-forward, 6=forward
int[] qcf = new array[] {2, 3, 6};

// Where you check for move transitions
if(input.CheckSequence(qcf, 16)) {
    ExecuteMove("Fireball");
}
票数 3
EN
页面原文内容由Game Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://gamedev.stackexchange.com/questions/43708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档