I am trying to implement an object moving on screen. In the long term it is an aircraft which is moving in real time and the screen is a scaled down map of reality. I haven't done such a thing before but think my "physics" is correct. Can this be done with an infinite loop in kotlin, and the image moving with reference to the time now in ms and what it was last time the loop ran? The loop runs but the screen goes blank, I am missing something. Code below with comments, think you can ignore the scaling etc, primary concern is I can't get something moving around the screen without this loop seemingly crash the device. There is another item on the view that isn't visible during the loop, this confirms that the aircraft object hasn't simply moved off screen.
package com.example.ifrtrainer
import android.os.Bundle
import android.util.DisplayMetrics
import androidx.activity.ComponentActivity
import com.example.ifrtrainer.databinding.GamescreenBinding
import kotlin.math.cos
import kotlin.math.sin
class MainActivity : ComponentActivity() {
lateinit var gamescreenbind : GamescreenBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
gamescreenbind = GamescreenBinding.inflate(layoutInflater)
setContentView(gamescreenbind.root)
gamescreenbind.button.setOnClickListener(){begingame()}
}
private fun begingame() {
//setContentView(gamescreenbind.root)
var play: Boolean = true
gamescreenbind.buttonkill.setOnClickListener(){play = false} //kills the game
var NMperpx = scale() //this is how many Nautical miles per pixel
var useraircraft = aircraft(NMperpx) //initiate the aircraft
var timeendloop: Long = System.currentTimeMillis()
while (play == true) {
useraircraft.moveaircraft(timeendloop) //submits current time to the loop
gamescreenbind.imageAircraft.setX(useraircraft.xpos.toFloat())
gamescreenbind.imageAircraft.setY(useraircraft.ypos.toFloat())
timeendloop = System.currentTimeMillis()
}
}
private fun scale():Double{
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
val inchwidth: Float = displayMetrics.widthPixels/displayMetrics.xdpi //width of screen in inches
val NMperinch: Double = 6.61/inchwidth *4.38 //on an IAP 6.61 inch width, 1 inch is 4.38 NM
val NMperpx: Double = NMperinch/displayMetrics.xdpi //how many NM per pixel, ultimate unit we're working in on screen
return NMperpx
}
}
class aircraft(NMperpx: Double){
var speed: Double = 100.0
var heading: Double = 0.0
var descentrate: Int = 0
var turnrate: Double = speed/10 + 7
var xpos: Double = 300.0
var ypos: Double = 1500.0
var speedpxpermilli: Double = 0.0025*NMperpx //how many pixels per ms we need to move to fly at 100kts
fun moveaircraft(looptime: Long){
var time: Long = System.currentTimeMillis()
xpos = xpos + sin(heading)*speedpxpermilli*(time-looptime)
ypos = ypos + cos(heading)*speedpxpermilli*(time-looptime)
}
}