Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

In fighting game, there is an important thing called input buffering. When your character is doing an action, you can input the next action that will activate as soon as possible (the buffer is 5-10 frames).

Has anyone already implemented, or knows the most efficient way to do this?

I thought of things like this:

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

Any better ideas? Thx.

share|improve this question

migrated from stackoverflow.com Nov 13 '12 at 15:42

This question came from our site for professional and enthusiast programmers.

2 Answers 2

How about you use a Queue<T>?

There are 4 significant members of Queue<T> you can use:

  1. Queue.Enqueue(T item) - put your item at the end of the queue.
  2. T Queue.Peek() - look at the first item without removing it.
  3. T Queue.Dequeue() - get and remove the first item.
  4. Queue.Count - check how many items are in queue.

Sample usage

Here's what could be a class representing moves:

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;
        }
    }
}

Your update checks to see if moves are elapsed:

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;
    }
}

To add a move to the queue, simply call

_moveQueue.Enqueue(new Move(MoveType.Fireball));

To get the current move, simply

Move currentMove = _moveQueue.Peek();
if(currentMove.MoveType == MoveType.Fireball)
   //...

Also - don't count the duration in frames, count it in seconds (or milliseconds if you must).

share|improve this answer
    
I'll try to use the queue system –  Pilispring Nov 13 '12 at 12:08

I have a really simple method of detecting special move sequences for my game Fearless Night.
It just stores the last 60 frames of input, but you can make it any length. I implemented a simple method for checking if a sequence has been executed. It's written in Lua, but I'll do my best to write it in C# for you.

We use integer values to represent directions based on a keyboard's number pad, but you can use anything that's comparable as a replacement for the input state. I simplified some things here, such as not accounting for a character's direction flipping when crossing over an opponent. Normally this would flip the forward and back directions for a special move input.

The algorithm simply checks each input state from the CurrentTick offset inside the input buffer back until maxDuration. This assumes that the buffer array is circular.

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;
    }
}

You can use it like such

// 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");
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.