Rather than ask lots of questions, I have studied first and below is my rather simple effort at a reaction timer. It was done as a learning exercise in gadget interaction and how to get a thread to work, rather than a precision timer. It may look very simple to most, but it took me a long while to figure out the thread part. I have commented the code as I understand it. It does work but now I am left with a question, am I on the right track with PureBasic coding?
Code: Select all
; -------------------------------------------
; Title: Reaction Timer
; Version: 1.1
; PB Ver: 4.00
;
; Author: George Jopling
;
; About:
; A simple reaction timer for novelty use.
;
; Use this code in any way you see fit.
; -------------------------------------------
;- Window Constants
Enumeration
#Window_0
EndEnumeration
;- Gadget Constants
Enumeration
#Spin_Random
#Button_Start
#Text_Seconds
#Text_Label_Spin
#Text_Label_Seconds
#Text_Status
EndEnumeration
Procedure timer()
SetGadgetText(#Text_Status, "[ Random delay started. Get ready... ]")
StartDelay.b=(GetGadgetState(#Spin_Random)) ;Obtain value of Spin Gadget.
RandomStart.w = Random(StartDelay) ;Use Spin Gadget number as maximum for randomising start delay.
If RandomStart = 0 ;0 is a valid output of Random(). Add 1 if random result is 0.
RandomStart = RandomStart + 1
EndIf
Delay(RandomStart*1000) ;Convert random delay number into milliseconds, as required by Delay().
key.w = GetKeyState_( #VK_SPACE) ;API keyboard call.
If key & $8000 ;Check to see if the Space bar is being pressed when Delay() expires;
DisableGadget(#Button_Start, 0)
DisableGadget(#Spin_Random, 0)
SetGadgetText(#Text_Status, "[ Cheat! ]") ;Display a cheat message if it is.
Else ;Space bar was not being pressed, continue with main reaction timer.
SetGadgetText(#Text_Status, "[ Go! Press the Space bar Now! ]")
Beep_(500,50) ;API function to make sound from the computer speaker.
StartTime.d = ElapsedMilliseconds() ;Obtain a time reference point when the reaction timer started.
Repeat ;Generate loop checking to see if the Space bar has been pressed. Update displays accordingly.
key.w = GetKeyState_( #VK_SPACE) ;API keyboard call.
If key & $8000 ;Check to see if the Space bar has been pressed.
DisableGadget(#Button_Start, 0)
DisableGadget(#Spin_Random, 0)
SetGadgetText(#Text_Status, "[ Another go? ]")
Break ;Break out of loop straight away if the Space bar has been pressed.
Else ;If Space bar has not been pressed, update timer display etc.
Delay(1) ;1 millisecond delay. Essential to prevent 100 per cent processor usage.
DisplayTime.f = ElapsedMilliseconds()-StartTime ;Obtain further time reference point and compare against start.
DisplayTimeSeconds.s = StrF(DisplayTime/1000, 3) ;Format display to 3 decimal places.
SetGadgetText(#Text_Seconds,DisplayTimeSeconds) ;Display it.
EndIf
Until DisplayTime = 10000 ;Loop until maximum wait time for Space bar press (10 seconds). End loop if reached.
If DisplayTime = 10000 ;If it is the maximimum wait time, update accordingly.
SetGadgetText(#Text_Status, "[ Slowcoach! Another go? ]")
DisableGadget(#Button_Start, 0)
DisableGadget(#Spin_Random, 0)
EndIf
EndIf
EndProcedure
Procedure Open_Window_0() ;Open the main window and display gadgets.
If OpenWindow(#Window_0, 410, 283, 264, 192, "Reaction Timer", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered | #PB_Window_WindowCentered )
If CreateGadgetList(WindowID(#Window_0))
SpinGadget(#Spin_Random, 170, 25, 55, 25, 1, 60) ;Set the spin gadget minimum value at 1 and maximum at 60.
SetGadgetState (#Spin_Random,10) : SetGadgetText(#Spin_Random,"10") ;Set the spin gadget default at 10.
ButtonGadget(#Button_Start, 85, 150, 80, 25, "Start Timer")
TextGadget(#Text_Seconds, 120, 105, 105, 20, "0.000", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Text_Label_Spin, 30, 30, 125, 25, "Random Delay Maximum", #PB_Text_Center)
TextGadget(#Text_Label_Seconds, 35, 105, 60, 25, "Seconds")
TextGadget(#Text_Status, 35, 70, 190, 20, "[ Click Start Timer button. ]")
EndIf
EndIf
EndProcedure
Procedure Event_Loop() ;Loop for events. Check to see what they are and process accordingly.
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #Spin_Random ;Process gadget event.
If GetGadgetState(#Spin_Random)<>Val(GetGadgetText(#Spin_Random)) ;Have gadget contents changed.
If EventType()=#PB_EventType_Change ;Has a value been typed into gadget.
SetGadgetState(#Spin_Random,Val(GetGadgetText(#Spin_Random))) ;Set gadget to current value.
Else
SetGadgetText(#Spin_Random,Str(GetGadgetState(#Spin_Random))) ;Put value of button change into gadget.
EndIf
EndIf
Case #Button_Start ;Start button pressed
SetGadgetText(#Text_Seconds, "0.000")
DisableGadget(#Button_Start, 1)
DisableGadget(#Spin_Random, 1)
ThreadTimer=CreateThread(@timer(),"") ;Create a thread for the timing processes and display updates.
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow ;Exit the program if the close window button is clicked.
EndProcedure
Open_Window_0() ;Call the Open Window procedure to initialise the program and display on screen.
Event_Loop() ;Call the Event Loop to check for events and process them.