Question

I'm working on a small Android game that handles canvas drawing on a working thread. After the game is over this thread should start the next activity, but somehow the UI thread seems to get blocked by starting a new function.

This is my games Main-Loop:

while(true)
    // Perform Ticks until the player makes a mistake
    c = _surfaceHolder.lockCanvas();
    if ((toDraw = rh.performTick()) == null) {
         lose();
         break;
     }
     _surfaceHolder.unlockCanvasAndPost(draw(toDraw,c));
}

The function performTick() processes the game logic and returns null when the game ends. draw()does the rendering. Both Functions work perfect - the problem is lose(), which does nothing than starting a new Activity:

    protected void lose() {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(_context, MainMenu.class);
                _context.startActivity(intent);
            }
        });
    }

When the Game ends, the new Activiy (MainMenu) starts normally but does not react on any touch events. There is no LogCat output and no Exception occuring. Even worse, lose()works normal when its called BEFORE the main loop starts.

I've been working on this for days now. I tried to start the Activity directly from the working Thread (without using a Handler in lose()) and searched the Internet for hours - nothing helps. It seems like the UI Thread is somehow blocked or caught in an infinite loop, and i have no idea how to fix this.

Everything is debugged on a Nexus 4 device.

Btw: MainMenu.onCreate() works normal when started another way.

Please help, MA3o

Was it helpful?

Solution

You don't unlock the canvas when the if statement is true. Break will get you out of the while, leaving the canvas locked.

while(true)
    // Perform Ticks until the player makes a mistake
    c = _surfaceHolder.lockCanvas();
    if ((toDraw = rh.performTick()) == null) {
         lose();
         break;
     }

     // this line won't be executed whether the if statement above is true
     _surfaceHolder.unlockCanvasAndPost(draw(toDraw,c));
}

You should unlock inside the if statement also (before or after lose()).

OTHER TIPS

Instead if While(true) you could have While(myVar) where myVar is a boolean that is true while game should be running and set to false when you call lose() In your case you continued to draw although you did not need to.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top