BerickCook ha espresso correttamente l'idea. Lascia i calcoli dove sono se funzionano correttamente ora.
Se puoi fare il calcolo prima e sei sicuro di non averne bisogno a metà partita, allora fallo prima. Altrimenti fallo dopo il caricamento. Se il calcolo durante il gioco è impercettibile, puoi farlo lì. Se a un certo punto la complessità si evolve e i calcoli diventano troppo pesanti, inizia l'ottimizzazione.
Ma una cosa: se i tuoi calcoli sono implementati per l'esecuzione a metà partita, puoi sempre forzarli ad eseguirli durante il caricamento.
Esistono numerose soluzioni:
- calcola / carica i percorsi durante la creazione / caricamento del livello
- utilizzare un secondo thread per calcolare i percorsi
- ottimizza i tuoi algoritmi
- utilizzare un sistema interrompibile se non si ha accesso al threading.
Ho visto e usato l'ultima opzione in un gioco del mercato di massa. Assicurati semplicemente di salvare correttamente tutti i dati necessari per riprendere il calcolo e controllare regolarmente il tempo / le operazioni rimanenti durante il calcolo.
A seconda del caso, il sistema interrompibile potrebbe fornire soluzioni preliminari e parziali che possono essere utilizzate evento prima della fine del calcolo.
Modifica : risposta a @Keeper
L '"algoritmo interrompibile" è stato utile solo a causa dei vincoli che avevamo. Fondamentalmente ci siamo indeboliti dalla mancanza di multithreading.
A un certo punto abbiamo avuto un gioco in cui l'IA ha dovuto calcolare grandi quantità di mosse basate su più dizionari. Durante questo calcolo tutte le animazioni si fermavano perché i dizionari venivano espansi con più dati e il set di dati contenente i dati veniva modificato e meno efficiente quando il gioco veniva adattato per il multiplayer (dove l'IA doveva interagire anche per le mosse del giocatore). Avevamo un solo thread disponibile per il loop del gioco (l'imperativo è che il codice multi-piattaforma deve essere eseguito su tutte le piattaforme supportate). A questo punto è stato deciso di interrompere l'algoritmo di calcolo in modo da poterlo interrompere. Pertanto non potevamo semplicemente usare il sistema ricorsivo che era in atto poiché le variabili non potevano essere salvate. Le funzioni sono state sostituite con oggetti che contenevano semplicemente tutte le variabili e i puntatori necessari per gli oggetti padre e figlio. Io non
- salva lo stato dei suoi calcoli correnti
- interrompere alla fine di un ciclo o durante un ciclo (quando un oggetto figlio interrompe)
- esci quando il tempo è scaduto
- riprendere da dove ha interrotto il riavvio di un ciclo nell'indice giusto o la chiamata dell'oggetto figlio che si trova attualmente nella parte superiore dello stack figlio.
- pulire tutto se il calcolo viene interrotto
- dare il miglior risultato parziale.
Solo le operazioni più costose sono state suddivise in oggetti separati e ci è voluto del tempo per trovare i posti giusti in cui potevamo interrompere i calcoli, ma alla fine funziona molto bene.
Abbiamo perso le prestazioni, ma le prestazioni percepite erano molto migliori per l'utente poiché le animazioni funzionavano senza problemi su tutte le piattaforme, tutte le piattaforme potevano quindi utilizzare i dizionari più grandi senza soffrire di animazioni discordanti o blocchi. Anche questo ci ha permesso di eseguire più istanze in parallelo quando ne avevamo bisogno in seguito.
Ovviamente ora su iPhone e iPad il gioco non ha bisogno di questo, usare un secondo thread sarebbe l'ideale. Ma sospetto che il codice sia ancora lì.