... it depends what you mean by 'action'. This modified version allows you to move around (cursor keys), but only polls the 'punch button' every second...
Graphics3D 800,600
cam = CreateCamera()
cube = CreateCube()
;message$ = "use 'P' To punch"
x# = 0 y# = 0
While Not KeyDown(1)
punchtimer = MilliSecs()-oldpunchtimer
kicktimer = MilliSecs()-oldkicktimer
If punchtimer > 1000
oldpunchtimer = MilliSecs()
punchmessage$ = DeterminePunchAction()
EndIf
If kicktimer > 500
oldkicktimer = MilliSecs()
kickmessage$ = DetermineKickAction()
EndIf
x = x + 0.1*(KeyDown(205)) - 0.1*(KeyDown(203))
y = y + 0.1*(KeyDown(200)) - 0.1*(KeyDown(208))
PositionEntity cube, x, y, 20
RenderWorld
Text 100,100,punchmessage$
Text 100, 200, kickmessage$
Flip
Wend
Function DeterminePunchAction$()
Select KeyHit(25)
Case 0
Return "use 'P' To punch"
Case 1
Return "punch"
Case 2
Return "superpunch"
Case 3
Return "sliding punch"
Default
Return "haymaker"
End Select
Return "error"
End Function
Function DetermineKickAction$()
Select KeyHit(37)
Case 0
Return "use 'K' To kick"
Case 1
Return "left kick"
Case 2
Return "right kick"
Case 3
Return "both legs kick !!!"
Default
Return "irish dancing"
End Select
Return "error"
End Function
... obviously fine-tuning of the timer is possible - although there will always be an element of 'lag' with this approach as Wolron suggests. I think this is acceptable for a 'special attack' button, but probably not for the main interaction (such as movement in the code above.)
Note that with this method it is possible to punch, kick and move all at the same time with no massively complicated 'hash table' of possible moves... If you have a huge number of possible attacks, Wolron's suggestion will require comprehensive design/coding. You will still have to decide on appropriate 'time-slices' with Wolron's approach in order to decide what 'not pressing a key' would look like !!!
I'm not suggesting that this code is a
good solution - just that in some situations it might have its merits.