使用OpenGL将游戏逻辑与Android的快节奏游戏分离的最佳方法是什么?

Gus*_*iel 14 android opengl-es

我一直在学习和制作小游戏,最近我决定尝试为Android开发游戏.

对我来说,从本机C++代码跳转到Android Java并不是那么难,但是让我头疼的是如何考虑如何将逻辑与渲染分开.

我一直在这里和其他网站上阅读:

最好不要为它创建另一个线程,因为Android肯定没有处理问题.

意思是代码是这样的:

public void onDrawFrame(GL10 gl) {
    doLogicCalculations();
    clearScreen();
    drawSprites();
}
Run Code Online (Sandbox Code Playgroud)

但我不确定这是否是最好的方法.因为如果我将逻辑放在GLRenderer::onDrawFrame方法中,我不认为我会这样.据我所知,这个方法只是为了绘制,如果我把逻辑放在那里,我可能会减慢帧的速度.更不用说在我的理解中它伤害了POO的概念.

我认为使用线程可能就是这样,这就是我的计划方式:

主要活动:

public void onCreate(Bundle savedInstanceState) {
    //set fullscreen, etc

    GLSurfaceView view = new GLSurfaceView(this);
    //Configure view

    GameManager game = new GameManager();
    game.start(context, view);

    setContentView(view);
}
Run Code Online (Sandbox Code Playgroud)

游戏管理:

OpenGLRenderer renderer;
Boolean running;
public void start(Context context, GLSurfaceView view) {
    this.renderer = new OpenGLRenderer(context);
    view.setRenderer(this.renderer);

    //create Texturelib, create sound system...

    running = true;
    //create a thread to run GameManager::update()
}

public void update(){
    while(running){
        //update game logic here
        //put, edit and remove sprites from renderer list
        //set running to false to quit game
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,OpenGLRenderer:

ListOrMap toDraw;
public void onDrawFrame(GL10 gl) {
    for(sprite i : toDraw)
    {
        i.draw();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个粗略的想法,并不完全完整.这种模式会将它们全部分开并且看起来会更好一点,但它是否最适合性能?

只要我研究过,大多数线程游戏的例子都使用canvas或surfaceview,那些不适合我的情况,因为我使用的是OpenGLES.

所以这是我的问题:

在使用OpenGLES时,哪种方法可以将我的游戏逻辑与渲染分开?线程我的申请?将逻辑放在一个单独的方法中,只需从draw方法中调用它?

Ste*_*ell 10

所以我认为有两种方法可以去这里.

  1. 执行以下所有更新onDrawFrame():这类似于使用GLUT,Android将尽可能多地调用此函数.(关闭它setRenderMode(RENDERMODE_WHEN_DIRTY).)此函数在其自己的线程(而不是UI线程)上调用,这意味着您在此处调用逻辑更新.你最初的问题是,这似乎有点混乱,我同意,但只是因为该功能被命名onDrawFrame().如果它被调用onUpdateScene(),那么更新逻辑将很好地适合这个模型.但这不是世界上最糟糕的事情,它是以这种方式设计的,人们也这样做.

  2. 给逻辑赋予自己的线程:这更复杂,因为现在你正在处理三个线程:用于输入的UI线程,onDrawFrame()用于绘制东西的渲染线程,以及用于连续处理输入和渲染数据的逻辑线程.如果您需要有一个非常准确的模型来使用它,即使您的帧速率正在下降(例如,精确的碰撞响应).这在概念上可能稍微清洁一些,但实际上并不干净.

我建议#1.你真的不需要#2.如果你这样做,你可以稍后添加它我想,但大多数人只是使用第一个选项,因为硬件足够快,所以你不必围绕它设计.


bri*_*dir 6

保持您的设计尽可能简单:)标准(也许是最好的)方法如下:

public void update(){
    while(running){
        updateAll();
        renderAll();
    }
}
Run Code Online (Sandbox Code Playgroud)

我会注意一些时刻:

  • 你需要调用后续updaterender方法,避免一次调用update两次
  • 如果您更喜欢多线程(我没有),请设计您的方法,以便只update写入数据和render读取
  • 请记住,OpenGL有自己的"线程",所以当你调用GL函数时它只向OpenGL发送一些命令(除了glFlush()- 它完成所有命令)