Pergunta

Estou trabalhando em um pequeno jogo Android que lida com o desenho de tela em um thread de trabalho.Após o término do jogo, esse thread deve iniciar a próxima atividade, mas de alguma forma o thread da UI parece ser bloqueado ao iniciar uma nova função.

Este é o Main-Loop dos meus jogos:

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));
}

A função performTick() processa a lógica do jogo e retorna null quando o jogo termina. draw()faz a renderização.Ambas as funções funcionam perfeitamente - o problema é lose(), que não faz nada além de iniciar uma nova 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);
            }
        });
    }

Quando o jogo termina, a nova atividade (Menu Principal) inicia normalmente, mas não reage a nenhum evento de toque.Não há saída do LogCat e nenhuma exceção ocorre.Pior ainda, lose()funciona normalmente quando é chamado ANTES do início do loop principal.

Estou trabalhando nisso há dias.Tentei iniciar a Activity diretamente do Thread de trabalho (sem usar um Handler em lose()) e pesquisei na Internet por horas - nada ajuda.Parece que o UI Thread está de alguma forma bloqueado ou preso em um loop infinito e não tenho ideia de como consertar isso.

Tudo é depurado em um dispositivo Nexus 4.

Por falar nisso: MainMenu.onCreate() funciona normalmente quando iniciado de outra maneira.

Por favor me ajude, ma3o

Foi útil?

Solução

Você não desbloqueia a tela quando a instrução if é verdadeira.O break vai tirar você do momento, deixando a tela travada.

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));
}

Você também deve desbloquear dentro da instrução if (antes ou depois de perder ()).

Outras dicas

Em vez disso, se While(true) você pode ter While(myVar) onde myVar é um booleano que é verdadeiro enquanto o jogo deve estar em execução e definido como falso quando você chama lose() No seu caso, você continuou a desenhar, embora não fosse necessário.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top