LibGDX开发常见问题

1.不同纹理绘制有遮挡,需要设置显示前后顺序,类似Z轴效果

简单的处理方案是建立不同的Group添加到Stage中,然后将actor添加到不同的Group中

class GameStage: Stage {
    private val bgGroup = Group()
    // 为了不让指导线有时候在水果后面 有时候显示在水果前面 设置预览水果到固定层级
    private val previewFruitGroup = Group()
    private val fruitGroup = Group()
    private val decorationGroup = Group()
    private val fgGroup = Group()
    init {
            // 层次从低到高  bgGroup在最底层
            root.addActor(bgGroup)
            root.addActor(fruitGroup)
            root.addActor(previewFruitGroup)
            root.addActor(decorationGroup)
            root.addActor(fgGroup)
    
        }
}

注意:这个方案较为简单,但是存在一个问题,如果通过Stage.actors获取内部的actor,只能获取到添加的这几个Group,如果想获取某个actor,需要再遍历具体添加到的Group,调用Group.getChildren来查找

2.不同线程可能导致抛异常问题

render函数运行在GLThread线程,我们在添加,移除actor,添加,移除刚体body的时候最好保持在一个线程,如果遇到抛异常,可以尝试将这个操作的代码放入到

Gdx.app.postRunnable { 
    // 目标代码
}
3.移除body抛出Native异常

这个时候一个有可能是因为问题2多线程导致,也可能是处于world模拟过程中移除被认为操作违法,一般处理是将需要移除的body先添加到集合或其他容器中,然后在render函数中,world模拟完成后进行统一的移除

private val mWorld = World(Vector2(0f, -20f), true)
private val bodys = ArrayList<Body>()

override fun render(delta: Float) {
        ScreenUtils.clear(Color.CLEAR)
        mWorld.step(Gdx.graphics.deltaTime, 6, 2)
        bodys.forEach {
            world.destroyBody(it)
        }               
        stage.act(Gdx.graphics.deltaTime)
        stage.draw()
}
4.AssetManager加载FreeType文字抛异常

根据官方文档,加载FreeType文字,只需要设置加载器

val assetManager = AssetManager(InternalFileHandleResolver(), false).apply {
    setLoader(
         FreeTypeFontGenerator::class.java,
         FreeTypeFontGeneratorLoader(fileHandleResolver)
    )
}

但是加载的时候会报BitmapFontParameter无法转换为FreeTypeFontParameter,这是因为AssetManager默认构造设置的BitmapFont加载器是setLoader(BitmapFont.class, new BitmapFontLoader(resolver)),所以我们需要构造像上面的构造参数defaultLoaders=false,然后自己收到设置需要用到的加载器

val assetManager = AssetManager(InternalFileHandleResolver(), false).apply {
        setLoader(
            FreeTypeFontGenerator::class.java,
            FreeTypeFontGeneratorLoader(fileHandleResolver)
        )
        setLoader(BitmapFont::class.java, FreetypeFontLoader(fileHandleResolver))

        setLoader(Music::class.java, MusicLoader(fileHandleResolver))
        setLoader(Pixmap::class.java, PixmapLoader(fileHandleResolver))
        setLoader(Sound::class.java, SoundLoader(fileHandleResolver))
        setLoader(TextureAtlas::class.java, TextureAtlasLoader(fileHandleResolver))
        setLoader(Texture::class.java, TextureLoader(fileHandleResolver))
        setLoader(Skin::class.java, SkinLoader(fileHandleResolver))
        setLoader(ParticleEffect::class.java, ParticleEffectLoader(fileHandleResolver))
        setLoader(
            com.badlogic.gdx.graphics.g3d.particles.ParticleEffect::class.java,
            com.badlogic.gdx.graphics.g3d.particles.ParticleEffectLoader(fileHandleResolver)
        )
        setLoader(PolygonRegion::class.java, PolygonRegionLoader(fileHandleResolver))
        setLoader(I18NBundle::class.java, I18NBundleLoader(fileHandleResolver))
        setLoader(Model::class.java, ".g3dj", G3dModelLoader(JsonReader(), fileHandleResolver))
        setLoader(Model::class.java, ".g3db", G3dModelLoader(UBJsonReader(), fileHandleResolver))
        setLoader(Model::class.java, ".obj", ObjLoader(fileHandleResolver))
        setLoader(ShaderProgram::class.java, ShaderProgramLoader(fileHandleResolver))
        setLoader(Cubemap::class.java, CubemapLoader(fileHandleResolver))
    }
5.Tween动画设置后不起作用问题

Tween动画使用步骤:

  1. 编写目标属性访问器 xxxAccessor 注意访问器数据设置是否正确,是否取错了数据index,或者设置错了属性 Tween的target默认是按照0,1,2的index存储
public Tween target(float targetValue) {
    targetValues[0] = targetValue;
    return this;
}

public Tween target(float targetValue1, float targetValue2) {
    targetValues[0] = targetValue1;
    targetValues[1] = targetValue2;
    return this;
}
  1. 注册访问器 Tween.registerAccessor(Actor::class.java, ActorAccessor()) (举例) 新增的动画容易忘记注册
  2. 编写Tween动画逻辑,使用Tween或者Timeline,调用start(TweenManager)
  3. 在act或者render方法中调用TweenManager.update()方法 使用动画的场景多了,容易忘了调用更新方法
6. Cannot run tasks on an executor that has been shutdown

这个是AssetManager使用过程可能出现的报错,一般是由于静态持有AssetManager对象,可能出现多次启动游戏,用的是同一个AssetManger对象,可能这个AssetManager对象已经调用过dispose(), 解决方法是避免静态持有,改为常规创建该对象,可以在ApplicationListener实现类的create方法内创建,方便全局使用,在ApplicationListener的dispose方法中调用assetManager.dispose()释放.

7. JNI critical lock held for xxx on Thread,app被杀掉

AssetManager加载资源过程可能会有这样的log出现,当占用时间很多的时候程序有可能被杀掉,可以看到程序占用内存飙升,导致命中了Android的杀程序的动作,主要图片内存占用,需要排查下是哪个资源造成,改变加载策略,或减少重复资源加载

持续更新中。。。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值