Reputation: 161
I am currently learning how to develop android applications. For my first app, I wanted to build a simple clicker with a primitive combat sistem.
In my code, I have created a Handler instance and a Runnable object. Inside of this "delayed loop" the enemy attacks the player instance every 3 seconds, dealing damage. Inside the loop I also test when the player's hp is less or equals 0; when the condition is met I want to stop the runnable object.
How do i do this? I tried calling a function stopCombat()
which contains Handler.removeCallbacks
, but i can't call a function before declaration. I tried putting .removeCallbacks(this)
inside run()
, but it also doesn't work.
val mainHandler = Handler(Looper.getMainLooper())
fun playerDied() {
ongoingFight = false
combatLog.append("${myPlayer.name} has been defeated!\n")
myPlayer.currentHitPoints = myPlayer.maxHitPoints / 2
myPlayer.gold = 0
gold.text = "${myPlayer.gold} gold"
}
val performTask = object : Runnable {
override fun run() {
val enemyHit = enemyAttack(myPlayer, myEnemy)
// Call a function to stop this thread if the condition is met:
if (myPlayer.takeDamage(enemyHit)) { //myPlayer.takeDamage returns true if hp <= 0
playerDied()
stopCombat() // called before declaration
mainHandler.removeCallbacks(this) // tried, doesn't work
}
playerHP.text = "${myPlayer.currentHitPoints} / ${myPlayer.maxHitPoints}"
combatLog.append("${myEnemy.name} deals $enemyHit damage!\n")
mainHandler.postDelayed(this, 3000)
}
}
fun stopCombat(){
mainHandler.removeCallbacks(performTask)
}
Upvotes: 0
Views: 617
Reputation: 93629
Set a boolean to determine if you’re going to post the runnable again
override fun run() {
val enemyHit = enemyAttack(myPlayer, myEnemy)
val died = myPlayer.takeDamage(enemyHit))
if (died)
playerDied()
playerHP.text = "${myPlayer.currentHitPoints} / ${myPlayer.maxHitPoints}"
combatLog.append("${myEnemy.name} deals $enemyHit damage!\n")
if (!died)
mainHandler.postDelayed(this, 3000)
}
Sorry for formatting—on my phone.
Upvotes: 1
Reputation: 760
I notice that you are using kotlin. I think you can use coroutines. It's more concise and lightweight. Cancellation and Timeouts
If you still want to use thread. Try the following code.
val executorService = Executors.newSingleThreadExecutor()
val runnables = Runnable {
}
val task = executorService.submit(runnables)
task.cancel(true)
Upvotes: 1