使用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对象。那么线程应该没有问题。