BerickCook a correctement exprimé l'idée. Laissez les calculs où ils sont s'ils fonctionnent correctement maintenant.
Si vous pouvez faire le calcul avant et que vous êtes sûr que vous n'en aurez pas besoin en milieu de partie, faites-le avant. Sinon, faites-le après le chargement. Si le calcul pendant le jeu est imperceptible, vous pouvez le faire à cet endroit. Si à un moment donné la complexité évolue et les calculs deviennent trop lourds, commencez à optimiser.
Mais une chose: si vos calculs sont mis en œuvre pour fonctionner en milieu de partie, vous pouvez toujours les forcer à être exécutés pendant le chargement de toute façon.
Il existe de nombreuses solutions:
- calculer / charger les chemins lors de la création / chargement de niveau
- utiliser un deuxième fil pour calculer les chemins
- optimisez vos algorithmes
- utilisez un système interruptible si vous n'avez pas accès au filetage.
J'ai vu et utilisé la dernière option dans un jeu grand public. Assurez-vous simplement de sauvegarder correctement toutes les données nécessaires à la reprise du calcul et vérifiez régulièrement le temps / les opérations restants pendant le calcul.
Selon votre cas, le système interruptible pourra donner des solutions préliminaires et partielles qui pourront être utilisées événement avant la fin du calcul.
Modifier : répondre à @Keeper
"L'algorithme interruptible" n'était utile qu'en raison des contraintes que nous avions. Fondamentalement, nous avons pallié au manque de multithreading.
À un moment donné, nous avions un jeu où l'IA devait calculer de grandes quantités de mouvements sur la base de plusieurs dictionnaires. Pendant ce calcul, toutes les animations s'arrêtaient car les dictionnaires étaient étendus avec plus de données et l'ensemble de données contenant les données était modifié et moins efficace lorsque le jeu était adapté pour le multijoueur (où l'IA devait interagir même pour les mouvements du joueur). Nous n'avions qu'un seul thread disponible pour la boucle de jeu (l'impératif étant que le code multi-plateforme doit s'exécuter sur toutes les plateformes prises en charge). À ce stade, il a été décidé de casser l'algorithme de calcul afin de pouvoir l'interrompre. Par conséquent, nous ne pouvions pas simplement utiliser le système récursif qui était en place car les variables ne pouvaient pas être enregistrées. Les fonctions ont été remplacées par des objets qui contenaient simplement toutes les variables et pointeurs nécessaires vers les objets parents et enfants. Je ne '
- enregistrer l'état de ses calculs actuels
- interrompre à la fin d'une boucle ou pendant une boucle (lorsqu'un objet enfant interrompt)
- sortir quand le temps est écoulé
- reprendre là où il s'est arrêté soit en redémarrant une boucle à l'index de droite, soit en appelant l'objet enfant actuellement en haut de sa pile enfants.
- tout nettoyer si le calcul est interrompu
- donner le meilleur résultat partiel.
Seules les opérations les plus coûteuses ont été divisées en objets séparés et il a fallu un certain temps pour trouver les bons endroits où nous pouvions arrêter les calculs, mais au final cela fonctionne très bien.
Nous avons perdu des performances, mais les performances perçues étaient bien meilleures pour l'utilisateur car les animations se déroulaient sans problème sur toutes les plates-formes, toutes les plates-formes pouvaient alors utiliser les plus grands dictionnaires sans souffrir d'animations saccadées ou de gels. Cela nous a également permis d'exécuter plusieurs instances en parallèle lorsque nous en avions besoin plus tard.
Bien sûr, maintenant, sur l'iPhone et l'iPad, le jeu n'en a plus besoin, l'utilisation d'un deuxième fil serait idéale. Mais je soupçonne que le code est toujours là.