首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LibGDX体系结构设计指南

LibGDX体系结构设计指南
EN

Stack Overflow用户
提问于 2018-11-03 22:30:47
回答 2查看 847关注 0票数 4

我处理了大量的体系结构设计模式和指南,以供选择,并遵循作为一个android客户端服务器应用程序开发人员。

最受欢迎的是:

  • MVP或MVVM
  • 洁净建筑
  • 存储库模式
  • 依赖注入技术
  • 等等..。

由于模式的严格规则,开发人员不得不承认模式本身只是推荐的,根本不需要Android。

LibGDX也是如此。LibGDX库没有提供严格的规则或要求,因此开发人员可以自由决定如何编写游戏。

所以问题是:

是否有一些建议,设计指南,甚至LibGDX游戏开发人员遵循的标准?我应该如何以其他开发人员很容易理解的方式编写代码(使用LibGDX)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-10 11:49:12

三年过去了,我可以自己回答这个问题了。

我发现使用ECS (实体组件-系统)是创建游戏的最佳方法。

使用这种方法,您将有3个不同的目的对象。顾名思义,它们是:

  • Entity --只是一个通用对象,它只包含一组component对象,通常是一个ID
  • Component -是一袋数据。没有逻辑只是普通的POJO。它包含的数据将定义包含组件的Entity的行为。
  • System -是你把逻辑放进去的地方。每个系统都应该处理一个entity当且仅当它包含一组非常特定的components
  • Engine --是一个场景的表示,所有的entities都在其中生活,并由systems处理。

实现这种方法的简单方法是使用阿什利库。它是ECS的一个轻量级实现。虽然我的经验表明,这是最好的情况下,真正的游戏。如果你想有非常具体的动画(甚至游戏对象),那么使用scene2d。

Scene2d代表了一种更熟悉的方法(对绝大多数开发人员来说)。它是放置在层次结构中的UI元素的图表。有非常有用的Action,可以用来实现您的动画。它也最适合任何你想在游戏中显示的UI。

因此,总而言之,我已经计算出,每个屏幕应该有几个类,才能有明确的分工。

  • Screen --我把它看作是运行代码的分支。它包含一个Engine (如果我们需要一个ECS)和一个Stage (如果我们需要一个UI)。处理所有游戏事件,用户输入和路由。
  • Engine容器,它知道如何管理它的系统、实体和组件.
  • Stage - UI容器,它知道什么UI元素应该存在,它们应该如何外观和行为。

kotlin中的简单示例(请注意,在我的实际项目中,我使用柯恩 DI将所有内容绑定在一起):

代码语言:javascript
复制
class MyGameScreen : Screen, MyGameEngine.Callback, MyGameStage.Callback {

    val engine = MyGameEngine(callback = this)
    val stage = MyGameStage(callback = this)

    override fun create() {
        engine.create()
        stage.create()
    }

    override fun render(delta: Float) {
        enigne.update(delta)
        stage.act(delta)
        stage.draw()
    }

    override fun dispose() {
        enigne.dispose()
        stage.dispose()
    }

    override fun buttonPress() {
        //handle button press
    }

    override fun onGameEvent(event: MyGameEngine.Event) {
        //handle some game event
    }

}

class MyGameEngine(
    private val callback: Callback
) : com.badlogic.ashley.core.PooledEngine() {

    fun create() {
        // create and add all your systems and entities
    }

    sealed class Event {
        // ...
    }

    interface Callback {
        fun onGameEvent(event: Event)
    }

}

class MyGameStage(
    private val callback: Callback
) : com.badlogic.gdx.scenes.scene2d.Stage() {

    val button1 = TextButton(...).apply {
        addClickListener { callback.buttonPress() }
    }
    
    val label1 = Label(...)

    // and so on

    fun create() {
        val root = Table().apply {
            // add all your actors to the root table
        }

        val rootContainer = Container(root).apply {
            setFillParent(true)
            fill()
            top()
        }

        addActor(rootContainer)
    }

    fun startSomeAnimation() {
        val action = Actions.sequence(
            // your animation
        )

        addAction(action)
    }

    interface Callback {
        fun buttonPress()
    }

}
票数 1
EN

Stack Overflow用户

发布于 2018-11-05 10:24:48

根据我的经验,没有一个标准是每个人都遵循的。libGDX开发人员来自不同的背景。有些人是日常生活中的后端开发人员,有些人只是业余爱好者,学习他们的第一种开发技能。

我看到许多libGDX开源项目都有典型的静态SomeManager.getInstance()调用,而我更喜欢传递引用(作为后端开发人员,您将了解这些优点-可测试性等等)。

即使libGDX后端本身也不遵循一种方法。有一些部分通过反射获得对管理器的引用(这并不好,因为您必须从混淆中排除此类类),还有一些部分使用静态getInstances()。

如果您也是HTML5,您还必须遵守一些基于GWT的限制,因此有时您不得不在开发Spring应用程序时采取一种您永远不会做的方式。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53136080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档