ShapeRenderer绘制Actor拖拽时边界偏移及缩放异常问题求助
修复ShapeRenderer与Batch变换矩阵不匹配的问题
你猜的没错,这个问题确实是因为ShapeRenderer没有同步Stage和Actor的变换矩阵导致的。Stage会自动处理SpriteBatch的投影和变换,但ShapeRenderer是独立的,必须手动让它和当前Actor的变换保持一致,才能让调试线和实际Actor的边界对齐。
下面是具体的修复方案,结合你的代码场景来调整:
1. 在Actor的draw方法中同步矩阵
在你的Bubble类的draw方法里,不要直接使用ShapeRenderer绘制,而是先同步Batch的矩阵到ShapeRenderer,再进行绘制。还要注意状态的保存和恢复,避免影响后续渲染:
class Bubble : Actor() { // 可以把ShapeRenderer作为参数传入,或者通过Stage获取 private lateinit var sr: ShapeRenderer fun setShapeRenderer(sr: ShapeRenderer) { this.sr = sr } override fun draw(batch: Batch, parentAlpha: Float) { // 先暂停Batch,避免状态冲突 batch.end() // 同步ShapeRenderer的矩阵到当前Batch的状态 sr.projectionMatrix = batch.projectionMatrix sr.transformMatrix = batch.transformMatrix sr.setColor(color.r, color.g, color.b, color.a * parentAlpha) sr.begin(ShapeRenderer.ShapeType.Line) // 绘制圆形边界:要基于Actor的实际位置、尺寸和缩放计算 val actualRadius = (width * scaleX) / 2f val centerX = x + originX * scaleX val centerY = y + originY * scaleY sr.circle(centerX, centerY, actualRadius) sr.end() // 恢复Batch状态,继续后续渲染 batch.begin() // 如果你的Actor还有其他用Batch绘制的内容,放在这里 // ... } }
2. 在Main类中正确初始化和传递ShapeRenderer
确保ShapeRenderer和Stage使用相同的视口矩阵,并且传递给Bubble实例:
class Main : ApplicationAdapter() { lateinit var stage: Stage lateinit var sr: ShapeRenderer lateinit var bubble: Bubble override fun create() { val viewport = ExtendViewport(800f, 600f) stage = Stage(viewport) sr = ShapeRenderer() bubble = Bubble().apply { setSize(100f, 100f) setPosition(400f, 300f) setShapeRenderer(sr) // 添加拖拽逻辑示例 addListener(object : DragListener() { override fun drag(event: InputEvent?, x: Float, y: Float, pointer: Int) { moveBy(x - lastDragX, y - lastDragY) } }) } stage.addActor(bubble) Gdx.input.inputProcessor = stage } override fun render() { Gdx.gl.glClearColor(0f, 0f, 0f, 1f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) stage.act() stage.draw() } override fun resize(width: Int, height: Int) { stage.viewport.update(width, height, true) // 同步ShapeRenderer的投影矩阵到视口相机 sr.projectionMatrix = stage.viewport.camera.combined } override fun dispose() { stage.dispose() sr.dispose() } }
3. 关键原理说明
Stage的Batch在绘制Actor时,会自动应用Actor的变换(位置、缩放、旋转)到自身的变换矩阵中,但ShapeRenderer不会自动继承这些变换。所以必须手动把Batch的projectionMatrix和transformMatrix赋值给ShapeRenderer,这样ShapeRenderer绘制的内容才会和Actor在Batch中的渲染处于同一个坐标空间。
另外,处理缩放时要注意:Actor的width/height是原始尺寸,实际渲染尺寸是width * scaleX/height * scaleY,同时要考虑Actor的原点设置,这样计算出的圆心和半径才会完全匹配Actor的实际边界。
内容的提问来源于stack exchange,提问作者Divelix
相关产品推荐
相关产品推荐

