BerickCook expressou a idéia corretamente. Deixe os cálculos onde estão, se funcionar corretamente agora.
Se você pode fazer o cálculo antes e tiver certeza de que não precisará deles no meio do jogo, faça-o antes. Caso contrário, faça-o após o carregamento. Se o cálculo durante o jogo for imperceptível, você poderá fazê-lo lá. Se em algum momento a complexidade evoluir e os cálculos se tornarem pesados demais, comece a otimizar.
Mas uma coisa: se seus cálculos forem implementados para rodar no meio do jogo, você sempre poderá forçá-los a serem executados durante o carregamento de qualquer maneira.
Existem inúmeras soluções:
- calcular / carregar os caminhos durante a criação / carregamento do nível
- use um segundo encadeamento para calcular os caminhos
- otimize seus algoritmos
- use um sistema interruptível se você não tiver acesso ao encadeamento.
Eu já vi e usei a última opção em um jogo de mercado de massa. Simplesmente certifique-se de salvar corretamente todos os dados necessários para o cálculo ser retomado e verifique regularmente o tempo / operações restantes durante o cálculo.
Dependendo do seu caso, o sistema interruptível pode fornecer soluções preliminares e parciais que podem ser usadas antes do término do cálculo.
Editar : respondendo a @Keeper
O "algoritmo interruptível" foi útil apenas por causa das restrições que tínhamos. Basicamente, paliamos a falta de multithreading.
Em um ponto, tivemos um jogo em que a IA precisava calcular grandes quantidades de movimentos com base em vários dicionários. Durante esse cálculo, todas as animações parariam porque os dicionários foram expandidos com mais dados e o conjunto de dados contendo os dados foi alterado e menos eficiente quando o jogo foi adaptado para multiplayer (onde a IA tinha que interagir mesmo para os movimentos do jogador). Tínhamos apenas um segmento disponível para o loop do jogo (o imperativo é o código de multiplataformas ser executado em todas as plataformas suportadas). Nesse ponto, foi decidido interromper o algoritmo de cálculo para podermos interrompê-lo. Portanto, não podíamos simplesmente usar o sistema recursivo existente, pois as variáveis não podiam ser salvas. As funções foram substituídas por objetos que simplesmente continham todas as variáveis e indicadores necessários para objetos pai e filho. Eu não'
- salvar o status de seus cálculos atuais
- interrupção no final de um loop ou durante um loop (quando um objeto filho interrompe)
- sair quando o tempo acabar
- continue onde parou de reiniciar um loop no índice correto ou de chamar o objeto filho atualmente no topo de sua pilha filho.
- limpe tudo se o cálculo for interrompido
- dê o melhor resultado parcial.
Apenas as operações mais caras foram divididas em objetos separados e levou algum tempo para encontrar os lugares certos onde poderíamos parar os cálculos, mas no final funciona muito bem.
Perdemos o desempenho, mas o desempenho percebido foi muito melhor para o usuário, pois as animações rodavam sem problemas em todas as plataformas; todas as plataformas podiam usar dicionários maiores sem sofrer animações ou congelamentos irregulares. Além disso, isso nos permitiu executar várias instâncias em paralelo quando precisávamos disso mais tarde.
Claro que agora no iPhone e iPad o jogo não precisa disso, usar um segundo segmento seria o ideal. Mas suspeito que o código ainda esteja lá.