Learning how to code QCB/F inputs


Quarter Circle Back/Forward inputs are the quintessential special move inputs!

(QCF + Punch) throws out the legendary Hadoken in Street Fighter

In this case, however, I want to implement Kim's Crescent Moon Slash, which is

(QCB + Kick)

When succesfully executed, it looks like this:

Peeking behind the curtain a bit, here's what the code for that looks like:

function Inputs:CheckQuarterCircleInput(character, finalDirection)
  local checks = {
    hasInputtedDown = false,
    hasInputtedDiagonal = false,
    hasInputtedFinalDirection = false,
  }
  local start <const> = #character.history.frames
  local stop <const> = math.max(start - 10, 1)

  for i = start, stop, -1 do
    local buttonState <const> = self:GetButtonState(character, i)
    local hasPressed <const> = {
      [directions.BACK] = buttonState.hasPressedBack,
      [directions.FORWARD] = buttonState.hasPressedForward,
    }
    local hasPressedFinalDirection <const> = hasPressed[finalDirection]
    local isPressing <const> = {
      [directions.BACK] = buttonState.isPressingBack,
      [directions.FORWARD] = buttonState.isPressingForward,
    }
    local isPressingFinalDirection <const> = isPressing[finalDirection]

    if (checks.hasInputtedFinalDirection) then
      if (checks.hasInputtedDiagonal) then
        if (checks.hasInputtedDown) then
          return true
        else
          if (
            (buttonState.hasPressedDown or buttonState.isPressingDown) and
            not isPressingFinalDirection
          ) then
            checks.hasInputtedDown = true
          end
        end
      else
        if (isPressingFinalDirection and buttonState.isPressingDown) then
          checks.hasInputtedDiagonal = true
        end
      end
    else
      if (
        (hasPressedFinalDirection or isPressingFinalDirection) and
        not buttonState.isPressingDown
      ) then
        checks.hasInputtedFinalDirection = true
      end
    end
  end
end

Forgive the nested if statements! 🙇‍♂️ We need to check the inputs in a specific order while disallowing a check if the previous one hasn't been performed!

In this abstraction, I wanted to make a generic Quarter Circle input check function that accepts whether to check against pressing Back or Forward. To add even more confusion, we're checking them in descending order, since we're traversing the button states backwards! 😅 Here's the gist, though:

  1. First, we check that the final direction was pressed (Back or Forward)
  2. Next, we check that the diagonal input was performed (Back + Down, or Forward + Down)
  3. Lastly, we check that Down was pressed

We check the last 10 frames for this, though the timing may change in the future. This allows for a bit of flexibility so that the player doesn't need to perform the input exactly. For example, in 10 frames they could input:

    1. Down (pressed)
    2. Down (held)
    3. Down + Back (held)
    4. Down + Back (held for another frame)
    5. Down + Back (held for yet another frame)
    6. Back (pressed)
    7. Back (held)
    8. Back (held for another frame)
    9. Back (held for yet another frame)
    10. Back (held for a whopping 4 frames!)

    And the Quarter Circle Back check is considered good enough!

    If you'd like to lambast my terribly formatted code, or have any suggestions, hit me up in comments!

    Get Untitled Fighting Game

    Download NowName your own price

    Leave a comment

    Log in with itch.io to leave a comment.