I have a function SendInstruction which send instructions to the user to press a button with label x for 3 seconds. I have four buttons with labels y,z and w.
fun SendInstruction(buttonLabel:String):String{
return buttonLabel
}
I have a counter that either increments by 20 if correct sent instruction matches user clicked button and decrements if not correct.
But when correct for 3 seconds then another instruction can be sent for button y otherwise user must pass button x to go to y and also must pass y to go to z and must pass z to go to w
Here is what i tried so far
var counter:Int = 0
GlobalScope.launch{
SendInstruction("click button x")
if(userclicked)//always true for 3 seconds
delay(3000)//check in 3s if instructions matches user clicked
counter =20
SendInstruction("click button y")
if(userclicked)//always true for 3 s
delay(3000)//check in 3s if instruction matches user clicked
else
counter = 0
//restart
}
But it just doesn't work, can anyone help me with this please.
CodePudding user response:
You could use a timeout pattern, like a reverse debounce catch, to help here. Here is an example, where you set a click target and a coroutine that will reset the target in 3 seconds. If you click the target in that time the coroutine is cancelled and you move to the next target.
private var job: Job? = null
private var target = ""
private var score = 0
fun onClick(btn: String, next: String) {
if(btn == target) {
advance(next)
}
else {
// Handle wrong click by starting over
reset()
}
}
fun advance(next: String) {
// Handle a correct click by cancelling
// the coroutine, updating the score,
// and setting the next target
// Cancel the timeout
job?.cancel()
// Add to the score
score = 20
// Set the next/end case
if(next.isEmpty()) {
SendInstruction("you won")
}
else {
updateTarget(next)
}
}
fun updateTarget(next: String) {
// Update the target, notify the user,
// and start a coroutine to reset
// the target in 3 seconds
target = next
SendInstruction("Click on $next")
// Reset the target after 3 seconds
// unless the coroutine is cancelled
// by a correct button click first
job = lifecycleScope.launch {
delay(3000)
reset()
}
}
fun reset() {
// Start over on a wrong click
// or a timeout. Alternately could
// just show "game over" and make
// them click "Go" or something to start over
job?.cancel()
target = ""
score = 0
updateTarget("x")
}
fun start() {
// Call to start the game, probably from onResume or when the user clicks "Go" or something
updateTarget("x")
}
// Call these when the specific buttons are clicked
fun onClickX() {
onClick("x", "y")
}
fun onClickY() {
onClick("y", "z")
}
fun onClickZ() {
onClick("z", "w")
}
fun onClickW() {
onClick("w", "")
}