Domanda

I try to develop a game for Android platform, using Libgdx library. For network, I use the Kryonet library.

I want to change screen when I'm sure that my application is connected to my server.
The network part seems work but I have a problem with threads: it's the Kryonet's thread which execute OpenGL, not the Libgdx thread:

public class MyGdxGame extends Game {
    public static int UDP_PORT = 55555, TCP_PORT = 55556;
    private Client client;

    @Override
    public void create() {
        /*
         * client connection
         * etc ...
         */
        client.addListener(new Listener() {
            private int nb = 0;

            @Override
            public void received(Connection connection, Object data) {
                super.received(connection, data);
                nb++;
                if (nb == 5) {
                    MyGdxGame.this.setSecondScreen();
                }
            }
        });
        setScreen(new First(this, client));
    }

    protected void setSecondScreen() {
        setScreen(new Second(this, client)); //This part should be executed by Libgdx thread ?!     
    }

Note that First and Second are both Screen class which just draw an image.

I have this exception when I try to launch Second Screen: Exception in thread "Client" java.lang.RuntimeException: No OpenGL context found in the current thread.

Can I force the LibGDX thread to execute instructions ? Is an other approach possible?

Thank's Jonathan

È stato utile?

Soluzione

In Libgdx only one thread (the thread that executes the app lifecycle callbacks) has a valid OpenGL context and can invoke OpenGL calls. You can post a Runnable to the GDX thread from your other threads to get it to execute stuff on behalf of other threads. Posted runnables will be executed before the next render callback is run. See Gdx.app.postRunnable()

In your case you could do something like this:

@Override
public void received(Connection connection, Object data) {
   super.received(connection, data);
   nb++;
   if (nb == 5) {
      final MyGdxGame g = MyGdxGame.this;
      Gdx.app.postRunnable(new Runnable() {
         public void run() {
            g.setSecondScreen();
         });
   }
}

Depending on how often this happens, you may want to avoid allocating a new Runnable on each callback, so if you make your MyGdxGame Runnable or make a custom Listener that implements Runnable you should be able to avoid the allocation.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top