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:
- First, we check that the final direction was pressed (Back or Forward)
- Next, we check that the diagonal input was performed (Back + Down, or Forward + Down)
- 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:
- Down (pressed)
- Down (held)
- Down + Back (held)
- Down + Back (held for another frame)
- Down + Back (held for yet another frame)
- Back (pressed)
- Back (held)
- Back (held for another frame)
- Back (held for yet another frame)
- 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
Untitled Fighting Game
| Status | In development |
| Author | robobeau |
| Genre | Fighting |
| Tags | Playdate, tiled |
More posts
- v0.6.5 (in which I reveal my versioning system isn't semantic, but a general vib...Mar 23, 2024
- v0.6.0 (or It's Never Too Early To Polish)Jan 15, 2024
- v0.5.2 (or Framerate Walk with Me)Sep 05, 2023
- v0.5.0 (or A Million Little Refactors)Jul 08, 2023
- v0.4.0!!!11!1Apr 09, 2023
- Been a while!Mar 09, 2023
- Got Butler set up, so here's v0.3.2!Jan 29, 2023
- Pre-alpha!Jan 22, 2023
- The Right Tool for the Job (or How I Learned to Stop Worrying and Love Tiled)Oct 02, 2022

Leave a comment
Log in with itch.io to leave a comment.