使用LibGDX与阿卡

问题描述:

我使用的是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循环分开来实现一些行为想拥有。

一般来说,当您使用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对象。那么线程应该没有问题。