LibGDX Box2D物理体数量增多导致下落速度变慢问题排查
问题
用LibGDX Box2D开发测试游戏时,物理体数量为5个时下落速度正常;增加至10、12个及以上时,下落速度逐渐变慢。十几个物理体理论上不该影响重力效果,求排查原因。
代码示例
class GameViewActivity : ApplicationAdapter() { companion object { private const val SCALE = 2.0f const val PIXEL_PER_METER = 100f private const val TIME_STEP = 1 / 60f private const val VELOCITY_ITERATIONS = 6 private const val POSITION_ITERATIONS = 20 private const val VELOCITY_Y = -9.85f private const val VELOCITY_X = 0f } private var orthographicCamera: OrthographicCamera? = null private var world: World? = null private var batch: SpriteBatch? = null private var ground: Ground? = null private var discList = ArrayList<Disc>() private var shapeRenderer: ShapeRenderer? = null override fun create() { orthographicCamera = OrthographicCamera() orthographicCamera!!.setToOrtho(false, Gdx.graphics.width / SCALE, Gdx.graphics.height / SCALE) world = World(Vector2(VELOCITY_X, VELOCITY_Y), false) world!!.setContactListener(WorldContactListener()) batch = SpriteBatch() val shape = PolygonShape() shape.setAsBox(orthographicCamera!!.viewportWidth, 2f) ground = Ground(world!!, shape) for (i in 1..12) { val d = Disc(world!!, 60f, 10f + i.toFloat()*2, 150f, 30f) discList.add(d) } } override fun render() { update() Gdx.gl.glClearColor(0.5f, 0.8f, 1f, 1f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) shapeRenderer = ShapeRenderer() shapeRenderer!!.begin(ShapeRenderer.ShapeType.Filled); shapeRenderer!!.color = Color.YELLOW; shapeRenderer!!.rect ( 0f, ground!!.body!!.position.y * PIXEL_PER_METER - 12f / 2 / SCALE, orthographicCamera!!.viewportWidth * SCALE, 2f * PIXEL_PER_METER ) shapeRenderer!!.end(); for (disc in discList) { val discRenderer = ShapeRenderer() discRenderer.begin(ShapeRenderer.ShapeType.Filled); discRenderer.color = disc.getColor() discRenderer.rect( 300f, disc.body!!.position.y * PIXEL_PER_METER , disc.getWidth() * SCALE, disc.getHeight() * SCALE ) discRenderer.end() } } private fun update() { world!!.step(TIME_STEP, VELOCITY_ITERATIONS, POSITION_ITERATIONS) cameraUpdate() } private fun cameraUpdate() { orthographicCamera!!.update() } }
原因排查与解决
核心问题:频繁创建ShapeRenderer导致性能暴跌
你的代码在render()方法里犯了两个严重的性能错误:
- 每次渲染都新建一个
shapeRenderer实例,而非复用已有对象 - 循环绘制每个
Disc时,都新建一个discRenderer,12个物体就会创建12个ShapeRenderer
ShapeRenderer是开销较大的OpenGL渲染对象,频繁创建销毁会触发频繁的垃圾回收(GC),导致游戏帧率骤降。而Box2D的物理模拟依赖固定时间步长(TIME_STEP = 1/60f),如果帧率低于60,每秒执行world.step()的次数不足,物理模拟速度就会变慢,表现为物体下落速度降低。
修复步骤
- 初始化阶段创建
ShapeRenderer
在create()方法中初始化shapeRenderer,避免每次渲染新建:
override fun create() { // ...其他初始化代码 shapeRenderer = ShapeRenderer() }
- 复用同一个
ShapeRenderer绘制所有物体
移除循环内的discRenderer,用同一个shapeRenderer批量绘制地面和所有圆盘:
override fun render() { update() Gdx.gl.glClearColor(0.5f, 0.8f, 1f, 1f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) shapeRenderer!!.begin(ShapeRenderer.ShapeType.Filled); // 绘制地面 shapeRenderer!!.color = Color.YELLOW; shapeRenderer!!.rect ( 0f, ground!!.body!!.position.y * PIXEL_PER_METER - 12f / 2 / SCALE, orthographicCamera!!.viewportWidth * SCALE, 2f * PIXEL_PER_METER ) // 绘制所有圆盘 for (disc in discList) { shapeRenderer!!.color = disc.getColor() shapeRenderer!!.rect( 300f, disc.body!!.position.y * PIXEL_PER_METER , disc.getWidth() * SCALE, disc.getHeight() * SCALE ) } shapeRenderer!!.end(); }
- 添加资源释放逻辑
在dispose()方法中释放ShapeRenderer,避免内存泄漏:
override fun dispose() { shapeRenderer?.dispose() world?.dispose() batch?.dispose() // 释放其他资源 }
- 优化物理时间步处理(可选)
如果帧率波动较大,建议用累计时间的方式调用world.step(),保证物理模拟速度稳定:
private var accumulator = 0f private fun update() { val deltaTime = Gdx.graphics.deltaTime accumulator += deltaTime // 累计足够时间步就执行物理模拟 while (accumulator >= TIME_STEP) { world!!.step(TIME_STEP, VELOCITY_ITERATIONS, POSITION_ITERATIONS) accumulator -= TIME_STEP } cameraUpdate() }
内容的提问来源于stack exchange,提问作者jdleung
相关产品推荐
相关产品推荐

