Here's a Brutus2D demo. Use space and arrow keys to play. The double-tap has to be done quickly otherwise it just gets registered as a single-tap. Try also to hold the space key for a while.
Have fun.
p.s. let me know if it is "playable."
' Demo of input control with tap, doulbe-tap and hold functionality
' 2. jun 2007
' u9 4T kallnet D0T fo
'
' Use space bar and arrow keys to play. The double-tap has to be done quickly
Option explicit
graphics.initialize 640, 480
key.initialize
Dim font : font = graphics.createfont( "system", 10 )
' Adjustable timings
Const HOLD_THRESHOLD = 150
Const DOUBLE_TAP_THRESHOLD = 60
Const TAP_END_THRESHOLD = 10
' Used for the state-machine. It's nicer to have names for the states
Const IDLE = 0
Const WAIT_RELEASE = 1
Const HOLD = 2
Const WAIT_DBLTAP = 3
Const DOUBLE_TAP = 4
Const TAP = 5
Dim state, eventTimer
state = IDLE
' --- Code for demonstrating the input control
Dim xBall, yBall, stateBall, eventTimerBall, jumpTimeBall
Const bIDLE = 0
Const bJUMPING = 1
Const bSHAKING = 2
stateBall = bIDLE
xBall = 320
yBall = 400
' --- end ------------------------------------
Do
Dim curTime
curTime = system.gettime()
Dim lastAction, lastActionTime
' Implemented as a state diagram
If state = IDLE Then
If key.pressed( vk_space ) Then
state = WAIT_RELEASE
eventTimer = curTime
End If
ElseIf state = WAIT_RELEASE Then
If curTime - eventTimer > HOLD_THRESHOLD Then
state = HOLD
lastAction = "hold"
ElseIf Not key.pressed( vk_space ) Then
state = WAIT_DBLTAP
eventTimer = curTime
End If
ElseIf state = HOLD Then
lastActionTime = curTime
If Not key.pressed( vk_space ) Then
state = IDLE
End If
ElseIf state = WAIT_DBLTAP Then
If key.pressed( vk_space ) Then
state = DOUBLE_TAP
lastAction = "double tap"
lastActionTime = curTime
ElseIf curTime - eventTimer > DOUBLE_TAP_THRESHOLD Then
state = TAP
eventTimer = curTime
lastAction = "tap"
lastActionTime = curTime
End If
ElseIf state = DOUBLE_TAP Then
If Not key.pressed( vk_space ) Then
state = IDLE
End If
ElseIf state = TAP Then
If curTime - eventTimer > TAP_END_THRESHOLD Then
state = IDLE
End If
End If
If lastActionTime And curTime - lastActionTime > 1000 Then
lastAction = ""
lastActionTime = False
End If
graphics.clear
' --- Code for demonstrating the input control
graphics.setline 40, 410, 600, 410, &hffffffff
If stateBall = bIDLE Then
yBall = 400
If state = hold Then
stateBall = bSHAKING
eventTimerBall = curTime
ElseIf state = TAP Then
stateBall = bJUMPING
jumpTimeBall = 1000
eventTimerBall = curTime + jumpTimeBall
ElseIf state = DOUBLE_TAP Then
stateBall = bJUMPING
jumpTimeBall = 3000
eventTimerBall = curTime + jumpTimeBall
End If
ElseIf stateBall = bJUMPING Then
yBall = yBall - sin(pi/2 + (curTime-(eventTimerBall-jumpTimeBall))/jumpTimeBall * pi) * 5
If yBall > 400 Then yBall = 400
If eventTimerBall < curTime Then
stateBall = bIDLE
End If
ElseIf stateBall = bSHAKING Then
xBall = xBall + cos( curTime/15 ) * min( (curTime - eventTimerBall)/1000, 3 )
If state = idle Then
stateBall = bIDLE
End If
End If
If key.pressed( vk_left ) Then
xBall = xBall - 2
ElseIf key.pressed( vk_right ) Then
xBall = xBall + 2
End If
graphics.setcircle xBall, yBall, 10, &hffffffff
graphics.settext "Ball state: " & stateBall, 10, 420, font, &hffffffff
' --- end ------------------------------------
graphics.settext "Use space button. Action performed: " & lastAction, 10, 10, font, argb( 255, 255, 255, 255 )
graphics.settext "There are constants defined at the start of the file to change timing. Do play around with them", 10, 26, font, argb( 255, 200, 200, 200 )
graphics.display
graphics.setfps 60
system.processMessages
Loop until key.pressed( vk_escape ) Or key.pressed( vk_windowx )
key.terminate
graphics.terminate