Libgdx 自定义 Actor 未触发 clicked 和 touchedDown 事件

Libgdx custom Actor not firing clicked and touchedDown events

我在接收自定义 actor 上的点击事件时遇到问题 class。 我可以使用现有的 UI 组件(例如按钮和标签)来做到这一点,但不能使用我的自定义 actor。我将它添加到舞台上,设置为 inputProcessor,我在舞台上的 render 方法中调用舞台上的 act,我从控制台输出中知道 act我的演员正在被召唤。然而,事件永远不会被解雇。我还应该看什么? 我的演员:

class TowerActor(val sprite: Sprite, val unit: Tower) : Actor() {

    init {
        touchable = Touchable.enabled
        addListener(TestListener())
        sprite.updatePosition(unit.position)
    }

    override fun draw(batch: Batch, parentAlpha: Float) {
        super.draw(batch, parentAlpha)
        sprite.draw(batch)
    }

    class TestListener : InputListener() {
        override fun touchUp(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int) {
            super.touchUp(event, x, y, pointer, button)
            println("touchUp")
            exitProcess(0)
        }

        fun clicked(event: InputEvent?, x: Float, y: Float) {
            println("clicked2")
            exitProcess(0)
        }
    }
}

我的舞台(去掉了不重要的部分):

class GameStage(
        val game: GameController,
        result: MapParser.Result,
        levelId: String? = null

) : Stage() {
    val level: Level = game.loadLevel(levelId ?: result.levelTypes.first().id)
    val gameRenderer: GameRenderer

    init {
        gameRenderer = GameRenderer(batch = batch as SpriteBatch, level = level, textureRepository = TextureRepository.fromTiles(result.tiles))
    }

    fun render(delta: Float) {
        act(delta)
        draw()
    }

    val towerActors: MutableMap<String, Actor> = mutableMapOf()
    val textureRepository = TextureRepository.fromTiles(result.tiles)

    override fun draw() {
        super.draw()
        level.container.towersForRead.forEach { unit ->
            val tower = towerActors.getOrPut(unit.id) {
                println("created tower")
                val sprite = Sprite(textureRepository.getRegion(unit.type))
                val t = TowerActor(sprite = sprite, unit = unit)
                addActor(t)
                t
            }
        }
    }
}

在我的主游戏 render 方法中,我直接调用 GameStage.render(我这里有更复杂的屏幕结构,但我直接调用它只是为了确保结构不会导致一个问题)。

这种方法有问题吗?还有什么问题?

Actor 的输入侦听器不是从他们自己的 act 方法调用的,而是在调用 Actor 层次结构中的 hit 方法后直接从舞台调用的,以确定哪些 Actors 与触摸点重叠。

我认为你的问题是你没有为你的 Actor 设置位置和大小,所以它的 hit 方法总是 return false。

我还想建议您不要使用 Sprite class,尤其是对于 Actors。 Sprite class 不仅仅是一个图像资源(它从 TextureRegion 扩展而来),而且还有一堆关于它的大小、颜色旋转、比例等的数据。所以从一般的角度来看,这个 class 确实关注点分离做得不好,因为它将图像资产与游戏状态数据混为一谈。它仅在 LibGDX 中用于粒子,这是一种高度优化的情况,您无需单独检查单个粒子的绘图数据,并且它们的数量很多,因此 class 需要尽可能紧凑。

但特别是当您将它与 Actor 结合使用时会出现问题,因为现在您的游戏状态数据存在于两个地方。 Actor和Sprite都包含了位置、颜色、旋转、缩放等数据,那么哪个是true数据呢?这是模棱两可的,而且试图让它们保持同步很容易出错。

相反,您应该使用 TextureRegion 而不是 Sprite。那么您的 Actor 的大小、位置和颜色只有一个可能的真实来源:Actor 的属性。