Android: FirstPersonCameraController: Multitouch

Estoy haciendo un juego 3D en primera persona en Libgdx y todo va bien. Tengo un pequeño problema con los controles cuando se ejecuta en dispositivos mobilees.

Si se presiona primero un button de dirección (arriba, abajo, izquierda o derecha), no se puede arrastrar alnetworkingedor de la pantalla (para mirar alnetworkingedor). Si arrastro primero por la pantalla, ambos funcionan juntos. El código está en Kotlin

class InputController : FirstPersonCameraController { private var gameRenderScreen: GameRenderScreen = GameRenderScreen() private val forwardButton = TextButton("Forward", Gui.skin) private val backwardButton = TextButton("Backward", Gui.skin) private val leftButton = TextButton("Left", Gui.skin) private val rightButton = TextButton("Right", Gui.skin) private val jumpButton = TextButton("Jump", Gui.skin) private val modeButton = TextButton("Mode", Gui.skin) @JvmField var isAdding = true constructor(camera: Camera) : super(camera) {} constructor(camera: Camera, gameRenderScreen: GameRenderScreen, stage: Stage) : super(camera) { this.gameRenderScreen = gameRenderScreen // create control if (Gdx.app.type == Application.ApplicationType.Android || Gdx.app.type == Application.ApplicationType.iOS) { var width: Float = Gdx.graphics.width / 10f var height: Float = Gdx.graphics.height / 10f forwardButton.setBounds(50f + width, 100f + (height * 2), width, height) stage.addActor(forwardButton) leftButton.setBounds(50f, 50f + height, width, height) stage.addActor(leftButton) rightButton.setBounds(50f + (width * 2), 50f + height, width, height) stage.addActor(rightButton) backwardButton.setBounds(50f + width, 10f, width, height) stage.addActor(backwardButton) jumpButton.setBounds(Gdx.graphics.width - width - 50f, 50f + height, width, height) stage.addActor(jumpButton) modeButton.setBounds(Gdx.graphics.width - width - 50f, 100f + (height * 2), width, height) stage.addActor(modeButton) } //Todo fix this as it stops touching working val multiplexer = InputMultiplexer() multiplexer.addProcessor(this) multiplexer.addProcessor(stage) Gdx.input.inputProcessor = multiplexer } override fun keyDown(keycode: Int): Boolean { if ((keycode == Input.Keys.SPACE || jumpButton.isPressed) && gameRenderScreen.isJump == false && gameRenderScreen.jumping == 0.0f) { gameRenderScreen.isJump = true } if (keycode == Input.Keys.ENTER || modeButton.isPressed) { isAdding = !isAdding } return super.keyDown(keycode) } // Called from Render loop fun updateControls() { if (Gdx.app.type == Application.ApplicationType.Android || Gdx.app.type == Application.ApplicationType.iOS) { if (forwardButton.isPressed) { keyDown(Input.Keys.W) } else { keyUp(Input.Keys.W) } if (backwardButton.isPressed) { keyDown(Input.Keys.S) } else { keyUp(Input.Keys.S) } if (leftButton.isPressed) { keyDown(Input.Keys.A) } else { keyUp(Input.Keys.A) } if (rightButton.isPressed) { keyDown(Input.Keys.D) } else { keyUp(Input.Keys.D) } if (modeButton.isPressed) { isAdding = !isAdding } else { } if (jumpButton.isPressed && gameRenderScreen.isJump == false && gameRenderScreen.jumping == 0.0f) { gameRenderScreen.isJump = true } else { } } } override fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean { hasMoved = true return super.touchDragged(screenX, screenY, pointer) } override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { hasMoved = false return super.touchDown(screenX, screenY, pointer, button) } override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { if (hasMoved == false) { gameRenderScreen.getObject(screenX, screenY) } return super.touchUp(screenX, screenY, pointer, button) } companion object { fun width(): Int { return Gdx.graphics.width } fun height(): Int { return Gdx.graphics.height } var hasMoved: Boolean = false } } 

Entonces, aquí está la class fija, una vez que te das count de que el dedo 2 es una input diferente, tiene sentido 🙂

 class InputController : FirstPersonCameraController { private var gameRenderScreen: GameRenderScreen = GameRenderScreen() private val forwardButton = TextButton("Forward", Gui.skin) private val backwardButton = TextButton("Backward", Gui.skin) private val leftButton = TextButton("Left", Gui.skin) private val rightButton = TextButton("Right", Gui.skin) private val jumpButton = TextButton("Jump", Gui.skin) private val modeButton = TextButton("Mode", Gui.skin) var myCamera: Camera var tmp2 = Vector3(); private var degreesPerPixel2 = 0.5f // stop to much dragging private val touchPos = Vector2() private val dragPos = Vector2() private val radius = 20f @JvmField var isAdding = true constructor(camera: Camera, gameRenderScreen: GameRenderScreen, stage: Stage) : super(camera) { this.gameRenderScreen = gameRenderScreen myCamera = camera // create control if (Gdx.app.type == Application.ApplicationType.Android || Gdx.app.type == Application.ApplicationType.iOS) { var width: Float = width() / 10f var height: Float = height() / 10f forwardButton.setBounds(50f + width, 100f + (height * 2), width, height) stage.addActor(forwardButton) leftButton.setBounds(50f, 50f + height, width, height) stage.addActor(leftButton) rightButton.setBounds(50f + (width * 2), 50f + height, width, height) stage.addActor(rightButton) backwardButton.setBounds(50f + width, 10f, width, height) stage.addActor(backwardButton) jumpButton.setBounds(Gdx.graphics.width - width - 50f, 50f + height, width, height) jumpButton.addListener(object : InputListener() { override fun touchDown(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int): Boolean { if (gameRenderScreen.isJump == false && gameRenderScreen.jumping == 0.0f) { gameRenderScreen.isJump = true } return super.touchDown(event, x, y, pointer, button) } }) stage.addActor(jumpButton) modeButton.setBounds(Gdx.graphics.width - width - 50f, 100f + (height * 2), width, height) modeButton.addListener(object : InputListener() { override fun touchDown(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int): Boolean { isAdding = !isAdding return super.touchDown(event, x, y, pointer, button) } }) stage.addActor(modeButton) } val multiplexer = InputMultiplexer() multiplexer.addProcessor(stage) multiplexer.addProcessor(this) Gdx.input.inputProcessor = multiplexer } override fun keyDown(keycode: Int): Boolean { if (keycode == Input.Keys.SPACE && gameRenderScreen.isJump == false && gameRenderScreen.jumping == 0.0f) { gameRenderScreen.isJump = true } if (keycode == Input.Keys.ENTER || modeButton.isPressed) { isAdding = !isAdding } Gdx.app.log("INPUT", "Keydown " + keycode) return super.keyDown(keycode) } // Called from Render loop fun updateControls() { if (Gdx.app.type == Application.ApplicationType.Android || Gdx.app.type == Application.ApplicationType.iOS) { if (forwardButton.isPressed) { keyDown(Input.Keys.W) } else { keyUp(Input.Keys.W) } if (backwardButton.isPressed) { keyDown(Input.Keys.S) } else { keyUp(Input.Keys.S) } if (leftButton.isPressed) { keyDown(Input.Keys.A) } else { keyUp(Input.Keys.A) } if (rightButton.isPressed) { keyDown(Input.Keys.D) } else { keyUp(Input.Keys.D) } } } override fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean { dragPos.set(screenX.toFloat(), height() - screenY.toFloat()) val distance = touchPos.dst(dragPos) if (distance <= radius) { Gdx.app.log("BUILDING", "Not Dragging " + distance) } else { Gdx.app.log("BUILDING", "Dragging " + distance) hasMoved = true var cutoff = width() * 0.75 if (screenX > cutoff && pointer == 1 && Gdx.app.type == Application.ApplicationType.Android || Gdx.app.type == Application.ApplicationType.iOS) { var deltaX = -Gdx.input.getDeltaX(1) * degreesPerPixel2 var deltaY = -Gdx.input.getDeltaY(1) * degreesPerPixel2 myCamera.direction.rotate(myCamera.up, deltaX) tmp2.set(myCamera.direction).crs(myCamera.up).nor() myCamera.direction.rotate(tmp2, deltaY) return true } } return super.touchDragged(screenX, screenY, pointer) } override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { hasMoved = false Gdx.app.log("INPUT", "touch Down " + pointer + " " + button) touchPos.set(screenX.toFloat(), height() - screenY.toFloat()); return super.touchDown(screenX, screenY, pointer, button) } override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { if (hasMoved == false) { gameRenderScreen.getObject(screenX, screenY) } Gdx.app.log("INPUT", "touch up " + pointer + " " + button) return super.touchUp(screenX, screenY, pointer, button) } companion object { fun width(): Int { return Gdx.graphics.width } fun height(): Int { return Gdx.graphics.height } var hasMoved: Boolean = false } }