2017-09-01 56 views
2

我使用的是LibGDX一起阿卡試驗和我有以下問題使用LibGDX與阿卡

ERROR] [09012017 174508.522] [WorldMap-akka.actor.default-dispatcher-3] [akkaWorldMapusergame] No OpenGL context found in the current thread. 
java.lang.RuntimeException No OpenGL context found in the current thread. 
    at org.lwjgl.opengl.GLContext.getCapabilities(GLContext.java124) 
    at org.lwjgl.opengl.GL11.glDepthMask(GL11.java1157) 
    at com.badlogic.gdx.backends.lwjgl.LwjglGL20.glDepthMask(LwjglGL20.java256) 
    at com.badlogic.gdx.graphics.g2d.SpriteBatch.begin(SpriteBatch.java170) 
    at com.badlogic.gdx.scenes.scene2d.Stage.draw(Stage.java127) 
    at org.anacletogames.modes.WorldMapScreen.renderContent(WorldMapScreen.scala90) 
    at org.anacletogames.modes.GameActor$$anonfun$receive$1.applyOrElse(GameActor.scala27) 
    at akka.actor.Actor$class.aroundReceive(Actor.scala480) 
    at org.anacletogames.modes.GameActor.aroundReceive(GameActor.scala13) 
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala525) 
    at akka.actor.ActorCell.invoke(ActorCell.scala494) 
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala257) 
    at akka.dispatch.Mailbox.run(Mailbox.scala224) 
    at akka.dispatch.Mailbox.exec(Mailbox.scala234) 
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java260) 
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java1339) 
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java1979) 
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java107) 

出現這種情況,只要我努力呈現阿卡演員內在的東西,或試圖內創建屏幕演員。

現在的演員可以這樣概括

class GameActor extends Actor with WithDelta 
{ 

    val fpsLogger = new FPSLogger 
    var screenBaseScreen = null 
    override def receive = { 
    case CreateGame(s)= screen= s 


    case Render = 

     updateDelta() 
     if(isTimeToRender) { 
     ---game logic and stuff --- 
     stage.draw() 
     } 
    } 

} 

當我打電話.draw()它打破,這使得有很大的意義,這是一個不同的線程。如果我在演員內部創建屏幕,則沒有任何變化,它只是在創建屏幕時中斷。現在,雖然這種行爲感覺符合邏輯,但是我能做些什麼來繞過LibGDX的這種侷限性嗎?有沒有辦法實現這一點?我保留一個大的遊戲角色並沒有問題,但我需要將演員的Game循環分開來實現一些行爲想擁有。

回答

1

一般來說,當您使用UI時,預計您會從單個線程(包含主事件循環)與UI元素進行交互。這是多種用途所需要的;例如,許多GUI庫依賴於一些不安全的全局狀態來同時從多個線程訪問。 OpenGL在這方面是相似的。

大多數GUI庫提供了一種在主GUI線程中運行一段代碼的方法。例如,Swing具有​​函數,而JavaFX提供了Platform.runLater。在基於OpenGL的框架中,它們很可能是太低級別的,不能爲您提供這樣的方法;你可能必須自己驅動事件循環。在這種情況下,您還必須確保圖形相關的代碼在主線程上手動運行。

事件循環通常看起來像這樣:

while (true) { 
    for (event <- pollEvents()) { 
    dispatch(event) 
    } 
    draw() 
    ensureFps(60) // ensures that no more than 60 iterations are executed per second 
} 

這裏dispatch()功能分析每個事件,其可以是用戶輸入,一些計時器或任何其他,並修改該應用程序的狀態,而draw()顯示器更新的狀態。這個循環總是在初始化GUI庫的主線程中運行,這一點很重要。如果你想把這個循環放到actor中,這可能會很棘手。

它應該工作,如果你確保演員總是運行在一個單一的線程。要做到這一點,你必須配置一個dispatcher,它將一個線程分配給你的演員。然後你必須在調度者內部執行全部你的GUI庫的初始化,或者至少在調度器上使用execute()方法(在後一種情況下,你必須確保執行者只包含一個線程)。然後你必須確保你總是在這個主要actor中使用你的庫GUI對象。那麼線程應該沒有問題。