I am diving into libgdx and used their sample game as a starting point.
I also added a touchpad to move the bucket. That was kind of easy and worked flawless. My additional idea was to make the touchpad disappear when not touching/clicking the screen and be shown again once you touch it. Basically to give the player the freedom to decide where he wants to have the touchpad located on the screen.
Watching this recording it works pretty good but obviously I don't want to make it follow the mouse constantly. So I tried to make the touchpad (which is an actor on my stage) invisible. As soon as I do that, I am losing the touch event being forwarded to the touchpad. See this recording.
My initial idea was to not have the pad constantly follow the mouse pointer (as I want to support touch screens at some point too). So the ideal approach I tried but failed to implement was to add the touchpad on any "down" event and and "move" event afterwards is dealt by the touchpad but that does not work. The stage keeps the primary target of the input event and the touchpad is not informed about anything. I tried it with an InputMultiplexer but failed with it as well...
Any ideas?
My main class:
import com.badlogic.gdx.ApplicationAdapter
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.InputEvent
import com.badlogic.gdx.scenes.scene2d.InputListener
import com.badlogic.gdx.scenes.scene2d.Stage
import com.badlogic.gdx.scenes.scene2d.ui.Touchpad
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable
import com.badlogic.gdx.utils.ScreenUtils
class MyGame : ApplicationAdapter() {
private lateinit var pad: Touchpad
private lateinit var stage: Stage
private lateinit var camera: OrthographicCamera
override fun create() {
// create the camera and the SpriteBatch
camera = OrthographicCamera().apply {
setToOrtho(false, 800f, 480f)
}
stage = Stage()
stage.addListener(object : InputListener() {
override fun touchDown(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int): Boolean {
println("tdown")
pad.isVisible = true
return super.touchDown(event, x, y, pointer, button)
}
override fun mouseMoved(event: InputEvent?, x: Float, y: Float): Boolean {
println("mmoved")
if (!pad.isVisible) {
pad.x = x - pad.width / 2f
pad.y = y - pad.height / 2f
}
return super.mouseMoved(event, x, y)
}
override fun touchUp(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int) {
println("tup")
pad.isVisible = false
super.touchUp(event, x, y, pointer, button)
}
})
Gdx.input.inputProcessor = stage;
val padBackground = TextureRegionDrawable(Texture(Gdx.files.internal("pad_circle.png")))
val padThumb = TextureRegionDrawable(Texture(Gdx.files.internal("pad_thumb.png")))
pad = Touchpad(10f, Touchpad.TouchpadStyle(padBackground, padThumb))
pad.addListener(object : InputListener() {
override fun enter(event: InputEvent?, x: Float, y: Float, pointer: Int, fromActor: Actor?) {
println("pad enter")
pad.isVisible = true
super.enter(event, x, y, pointer, fromActor)
}
override fun exit(event: InputEvent?, x: Float, y: Float, pointer: Int, toActor: Actor?) {
pad.isVisible = false
println("pad exit")
super.exit(event, x, y, pointer, toActor)
}
})
pad.isVisible = false
stage.addActor(pad)
}
override fun render() {
ScreenUtils.clear(0f, 0f, 0.2f, 1f)
camera.update()
stage.act(Gdx.graphics.deltaTime)
stage.draw()
}
override fun dispose() {
}
}