2011-12-15 31 views
14

我一直在研究和製作小遊戲,最近我決定嘗試爲Android開發遊戲。使用OpenGL將遊戲邏輯與用於Android的快節奏遊戲渲染分離的最佳方法?

對我來說,從本地C++代碼跳轉到Android Java並不難,但是讓我頭痛的是如何能夠保持與渲染分離的邏輯。

我一直在讀在這裏和其他網站上:

最好是肯定有處理沒有問題,不爲它創建另一個線程,只是因爲 Android將。

含義代碼將是這樣的:

public void onDrawFrame(GL10 gl) { 
    doLogicCalculations(); 
    clearScreen(); 
    drawSprites(); 
} 

但我不知道那將是最好的辦法。因爲我不認爲我喜歡如果將我的邏輯放在GLRenderer::onDrawFrame方法內的樣子。據我所知,這種方法只是爲了繪製,如果我把邏輯放在那裏,我可能會放慢幀速度。更不用說在我的理解中它傷害了「公安條例」的概念。

我覺得用線程可能是這樣,這是我的打算:

主要活動:

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); 
} 

遊戲管理:

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 
    } 
} 

最後,OpenGLRenderer:

ListOrMap toDraw; 
public void onDrawFrame(GL10 gl) { 
    for(sprite i : toDraw) 
    { 
     i.draw(); 
    } 
} 

這是一個粗略的想法,並不完整。 這種模式會保持所有的分離,看起來會更好一點,但它是最好的性能?

只要我研究過,線程遊戲的大多數示例都使用canvas或surfaceview,那些將不適合我的情況,因爲我使用的是OpenGLES。

因此,這裏是我的問題:

這是使用OpenGLES當我 遊戲邏輯從繪製中分離出來的最佳方法?線程我的 應用程序?把邏輯放在一個單獨的方法中,並從 中調用它的繪製方法?

回答

10

所以我認爲有兩種方法可以到這裏。

  1. 是不是所有的更新從onDrawFrame()這類似於使用GLUT,和Android會盡可能多地調用這個函數。 (關掉setRenderMode(RENDERMODE_WHEN_DIRTY)。)這個函數在它自己的線程(而不是UI線程)上被調用,這意味着你在這裏調用你的邏輯更新。你最初的問題是,這看起來有點混亂,我同意,但只是因爲該功能被命名爲onDrawFrame()。如果它被稱爲onUpdateScene(),那麼更新邏輯將很適合這個模型。但這不是世界上最糟糕的事情,它是這樣設計的,人們也這樣做。

  2. 給邏輯它自己的線程:這是更復雜,因爲現在你正在處理三個線程:輸入UI線程,該線程渲染爲onDrawFrame()畫的東西,並與兩個連續工作的邏輯線程輸入和渲染數據。如果你需要有一個真正準確的模型,即使幀速下降(例如,精確的碰撞響應),也可以使用它。這在概念上可能會更清潔一點,但並不實際上更清潔。

我會推薦#1。你真的不需要#2。如果你這樣做,你可以在後面添加它,但大多數人只是使用第一個選項,因爲硬件足夠快,所以你不必圍繞它進行設計。

6

讓您的設計儘可能簡單:) 標準(也許是最好的)方法如下:

public void update(){ 
    while(running){ 
     updateAll(); 
     renderAll(); 
    } 
} 

我會注意的一些時刻:

  • 你需要連續呼叫updaterender方法,避免每次呼叫update
  • 如果您更喜歡m ultithreading(我不知道),設計自己的方法,這樣update將數據寫入和render只讀取
  • 記住,OpenGL的有它自己的「線程」,所以,當你調用GL函數只發送一些命令的OpenGL(除glFlush() - 它完成所有的命令)
+0

嗯,作爲你的最後一個主題摘要,OpenGLrenderer的onDrawFrame在另一個線程上調用?或者只是作爲請求發送到與GL相關的其他線程的gl.GLxxx()。 – 2011-12-15 16:05:09

+0

@Gtoknu當你調用`onDrawFrame()`時,你在另一個線程中。看到這裏:http://developer.android.com/reference/android/opengl/GLSurfaceView.Renderer.html – 2011-12-15 16:24:04