diff --git a/fcore/constants.sml b/fcore/constants.sml index 104b3a5..bc104ba 100644 --- a/fcore/constants.sml +++ b/fcore/constants.sml @@ -42,4 +42,6 @@ struct val moveBatY = 2 val moveProjectileBy = 11 + + val keyDelay = 0.3 end diff --git a/fcore/options/options-type.sml b/fcore/options/options-type.sml index d1c7aa9..bc5145c 100644 --- a/fcore/options/options-type.sml +++ b/fcore/options/options-type.sml @@ -10,7 +10,7 @@ sig | SAVE_BUTTON | CANCEL_BUTTON - type options_type = {focus: focus} + type options_type = {focus: focus, lastUpPress: real, lastDownPress: real} val initial: options_type end @@ -27,7 +27,7 @@ struct | SAVE_BUTTON | CANCEL_BUTTON - type options_type = {focus: focus} + type options_type = {focus: focus, lastUpPress: real, lastDownPress: real} - val initial = {focus = LEFT_KEY} + val initial = {focus = LEFT_KEY, lastUpPress = 0.0, lastDownPress = 0.0} end diff --git a/fcore/options/options-update.sml b/fcore/options/options-update.sml index 9e9d177..12a0b76 100644 --- a/fcore/options/options-update.sml +++ b/fcore/options/options-update.sml @@ -2,42 +2,94 @@ structure OptionsUpdate = struct open OptionsType - fun default (options, userKeys) = - {mode = GameType.OPTIONS options, userKeys = userKeys} + fun default (options: OptionsType.options_type, userKeys) = + let + val {focus, ...} = options + (* `default` function is called when no keys are pressed + * so set up pressed/down pressed both to 0 + * as neither is being pressed. *) + val options = {focus = focus, lastUpPress = 0.0, lastDownPress = 0.0} + in + {mode = GameType.OPTIONS options, userKeys = userKeys} + end - fun withFocus (newFocus, userKeys) = - {mode = GameType.OPTIONS {focus = newFocus}, userKeys = userKeys} + fun moveFocusUp (options, newFocus, userKeys, time) = + let + val {focus, lastUpPress, ...} = options + (* only switch to newFocus if it is time for key delay to be triggered. + * We set lastDownPress to 0 because up is currently being pressed instead + * so we don't want to a key delay for down. *) + val options = + if lastUpPress + Constants.keyDelay <= time then + {focus = newFocus, lastUpPress = time, lastDownPress = 0.0} + else + {focus = focus, lastUpPress = lastUpPress, lastDownPress = 0.0} + in + {mode = GameType.OPTIONS options, userKeys = userKeys} + end + + fun moveFocusDown (options, newFocus, userKeys, time) = + let + val {focus, lastDownPress, ...} = options + val options = + if lastDownPress + Constants.keyDelay <= time then + {focus = newFocus, lastUpPress = 0.0, lastDownPress = time} + else + {focus = focus, lastUpPress = 0.0, lastDownPress = lastDownPress} + in + {mode = GameType.OPTIONS options, userKeys = userKeys} + end fun update (options, input: FrameInputType.t, userKeys, time) = case #focus options of LEFT_KEY => - if #downHeld input then withFocus (RIGHT_KEY, userKeys) - else default (options, userKeys) + if #downHeld input then + moveFocusDown (options, RIGHT_KEY, userKeys, time) + else + default (options, userKeys) | RIGHT_KEY => - if #upHeld input then withFocus (LEFT_KEY, userKeys) - else if #downHeld input then withFocus (UP_KEY, userKeys) - else default (options, userKeys) + if #upHeld input then + moveFocusUp (options, LEFT_KEY, userKeys, time) + else if #downHeld input then + moveFocusDown (options, UP_KEY, userKeys, time) + else + default (options, userKeys) | UP_KEY => - if #upHeld input then withFocus (RIGHT_KEY, userKeys) - else if #downHeld input then withFocus (DOWN_KEY, userKeys) - else default (options, userKeys) + if #upHeld input then + moveFocusUp (options, RIGHT_KEY, userKeys, time) + else if #downHeld input then + moveFocusDown (options, DOWN_KEY, userKeys, time) + else + default (options, userKeys) | DOWN_KEY => - if #upHeld input then withFocus (UP_KEY, userKeys) - else if #downHeld input then withFocus (JUMP_KEY, userKeys) - else default (options, userKeys) + if #upHeld input then + moveFocusUp (options, UP_KEY, userKeys, time) + else if #downHeld input then + moveFocusDown (options, JUMP_KEY, userKeys, time) + else + default (options, userKeys) | JUMP_KEY => - if #upHeld input then withFocus (DOWN_KEY, userKeys) - else if #downHeld input then withFocus (ATTACK_KEY, userKeys) - else default (options, userKeys) + if #upHeld input then + moveFocusUp (options, DOWN_KEY, userKeys, time) + else if #downHeld input then + moveFocusDown (options, ATTACK_KEY, userKeys, time) + else + default (options, userKeys) | ATTACK_KEY => - if #upHeld input then withFocus (JUMP_KEY, userKeys) - else if #downHeld input then withFocus (SAVE_BUTTON, userKeys) - else default (options, userKeys) + if #upHeld input then + moveFocusUp (options, JUMP_KEY, userKeys, time) + else if #downHeld input then + moveFocusDown (options, SAVE_BUTTON, userKeys, time) + else + default (options, userKeys) | SAVE_BUTTON => - if #upHeld input then withFocus (ATTACK_KEY, userKeys) - else if #downHeld input then withFocus (CANCEL_BUTTON, userKeys) - else default (options, userKeys) + if #upHeld input then + moveFocusUp (options, ATTACK_KEY, userKeys, time) + else if #downHeld input then + moveFocusDown (options, CANCEL_BUTTON, userKeys, time) + else + default (options, userKeys) | CANCEL_BUTTON => - if #upHeld input then withFocus (SAVE_BUTTON, userKeys) + if #upHeld input then moveFocusUp (options, SAVE_BUTTON, userKeys, time) else default (options, userKeys) end