LibGDX如何判断Stage中的Actor对用户是否可见?
问题根因
Actor.isVisible()仅返回当前组件自身的visible属性值,不会校验以下影响实际可见性的场景:
- 组件的任意父级容器
visible属性为false - 组件被层级更高的其他组件完全遮挡
- 组件坐标超出Stage/父容器的裁剪区域
- 复用Dialog场景下,调用
hide()方法后未同步修改自身的visible属性,导致属性值和实际显示状态不一致
实际可见性判断方案
基础场景(含父级可见性校验)
普通复用Dialog的场景用该方法即可覆盖90%以上的误判情况:
public boolean isComponentVisible(Actor actor) { if (actor == null) return false; // 校验自身可见属性 if (!actor.isVisible()) return false; // 递归校验所有父级可见属性 Group parent = actor.getParent(); while (parent != null) { if (!parent.isVisible()) return false; parent = parent.getParent(); } // 校验组件是否已挂载到Stage渲染树中 return actor.getStage() != null; }
如果你的Dialog不可见是因为调用hide后没有移出Stage,单独判断dialog.getStage() == null就能直接解决问题
需要校验是否在可视区域内
如果要排除组件在视口外的情况,在上述判断基础上补充边界校验即可:
// 获取组件在Stage坐标系下的左上角坐标 Vector2 position = actor.localToStageCoordinates(new Vector2(0, 0)); // 构建组件边界矩形 Rectangle actorRect = new Rectangle(position.x, position.y, actor.getWidth(), actor.getHeight()); // 构建Stage可视区域矩形 Rectangle viewportRect = new Rectangle(0, 0, stage.getWidth(), stage.getHeight()); // 判断是否有重叠区域 return viewportRect.overlaps(actorRect);
遮挡校验(特殊场景用)
如果需要确认组件没有被更高层级的其他组件完全遮挡,需要遍历Stage中所有层级高于当前组件的元素,判断是否完全覆盖当前组件的显示区域,该操作性能开销较高,普通业务场景无需使用。
复用Dialog场景的简化优化
你可以在调用dialog.hide()时手动执行dialog.setVisible(false),调用stage.show(dialog)时手动执行dialog.setVisible(true),后续直接调用dialog.isVisible()即可得到准确结果,不需要额外编写判断逻辑。
内容的提问来源于stack exchange,提问作者user2342558
相关产品推荐
相关产品推荐

