【问题标题】:Libgdx custom Actor not firing clicked and touchedDown eventsLibgdx 自定义 Actor 未触发 clicked 和 touchDown 事件
【发布时间】:2020-07-22 13:09:20
【问题描述】:

我无法在我的自定义 Actor 类上接收点击事件。 我可以使用现有的 UI 组件(例如按钮和标签)来做到这一点,但不能使用我的自定义角色。我将它添加到舞台,设置为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(我在这里有更复杂的屏幕结构,但我直接调用它只是为了确保结构不会导致问题)。

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

【问题讨论】:

    标签: kotlin libgdx


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 感谢您的提示!我删除了精灵并改用了 TextureRegion。我现在将高度、宽度、x 和 y 设置为Actor。依然没有。这是你的意思吗?
    • 我做了一些挖掘,因为你也用hit 方法给出了提示。我的演员的hit 返回自己,当我在范围内点击时,所以 hit 显然按预期工作,问题必须在其他地方。
    • 然后它会冒泡到舞台,然后返回。
    • 实际上我没有在听touchDownclicked 所以它现在起作用了。很确定以前没有,所以我希望设置演员的大小和位置可以修复它。
    猜你喜欢
    • 1970-01-01
    • 2017-01-22
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多