Un thread séparé pour la boucle de jeu est-il obligatoire pour les jeux simples?

10

Je suis nouveau dans le développement de jeux. Afin d'apprendre, je recrée ce jeu sur la plateforme Android. Vous pouvez voir la vidéo du jeu sur le lien ci-dessus. C'est un jeu simple.

J'ai lu beaucoup d'articles sur le démarrage du développement de jeux, presque tous recommandés d'utiliser une boucle de jeu sur un thread séparé, ce qui est logique pour d'autres jeux. Cependant, pour ce jeu particulier, dois-je démarrer un thread séparé?

jin
la source
Pas sûr que ce soit un doublon, car il s'agit d'Android. Il existe d'autres considérations sur le threading dans une plate-forme Java qui sont différentes de cette question.
Sean Middleditch

Réponses:

8

Une boucle de jeu est généralement recommandée car elle est simple . Presque tous les jeux peuvent être correctement développés et exécutés en utilisant une boucle, et la plupart des jeux en auraient besoin pour fonctionner correctement.

Par exemple, la plupart des moteurs physiques nécessitent des mises à jour constantes et fiables pour une simulation correcte. Les animations et autres contenus dynamiques et graphiques doivent être mis à jour à chaque changement, etc ... Aka quelque chose que vous obtenez pratiquement gratuitement en utilisant une boucle.

Sachez maintenant que votre boucle n'a pas à s'exécuter sur un thread séparé. En fait, la plupart des jeux exécuteront la boucle sur le thread principal pour plus de simplicité. Même mes projets Android suivent ce principe.

Maintenant, la vraie question ici est quelle alternative proposez- vous ? Si vous avez une autre idée sur la façon d'obtenir des entrées de manière fiable, de faire des mises à jour et de dessiner des cadres qui vous conviennent, alors allez-y! Sinon, une boucle de jeu pourrait être le moyen le plus simple de démarrer.


la source
L'alternative à laquelle je pense est de mettre à jour l'écran en utilisant le fil principal lui-même puisque toutes les actions sont en série - le joueur glisse sur les boules de même couleur, puis toutes les boules touchées disparaissent, les boules restantes tombent sous gravité avec les boules de remplacement.
jin
Vous ne demandez donc pas si une boucle est requise? Votre principale préoccupation est de savoir si elle doit être sur un thread séparé, n'est-ce pas?
AturSams
1
correct. ma question concerne le fil et non la boucle. pour un jeu aussi simple (même si je serai chanceux de pouvoir faire un tel jeu) dois-je générer un nouveau thread ou tout peut être fait sur le thread principal?
jin
1
Non, ce n'est pas nécéssaire. Tant que vous avez une boucle , il n'est pas nécessaire de créer une deuxième boucle .
@jin, vous devriez vraiment changer le titre et la façon dont vous écrivez votre question.
vallentin
5

Non , un thread séparé n'est pas requis. Si vous ne faites rien de trop intense (ce qui ne semble pas être le cas dans le jeu que vous nous avez montré), tout peut être fait sur le fil principal.

Un deuxième thread est requis si vous effectuez beaucoup de traitement ou rencontrez des problèmes avec l'interface utilisateur / l'entrée qui ne répond plus. Par exemple, dans les jeux plus complexes, vous ne voulez pas que l'interface utilisateur / l'entrée ne réponde pas lorsque l'IA calcule son prochain mouvement. Étant donné que votre jeu semble répondre principalement aux entrées des utilisateurs et mettre à jour les visuels, un deuxième thread n'est pas requis.


Répondre à la question initiale "Une boucle est-elle requise".

Non , mais les alternatives sont plus compliquées, plus difficiles à mettre en œuvre et rarement utilisées.

Les jeux sont par définition interactifs. Au minimum, cela attend l'entrée et la mise à jour de la sortie. La façon la plus simple de le faire est d'utiliser une boucle. Il n'est pas nécessaire de générer un nouveau thread pour cela.

Même si le jeu que vous avez mentionné semble simple, il a des visuels et des sons interactifs et il met constamment à jour ceux basés sur les entrées des utilisateurs.

Il n'y a pas non plus beaucoup d'alternatives à une boucle de jeu. Une sorte de système basé sur les interruptions pourrait être possible. Cependant, de tels systèmes augmentent la complexité et réduisent d'autres facteurs comme le déterminisme. Il y a une raison pour laquelle les boucles de jeu sont si courantes, elles sont faciles à mettre en œuvre, faciles à comprendre, flexibles et font un excellent travail.

MichaelHouse
la source
La seule fois où j'ai rencontré des interruptions de niveau inférieur, c'est lorsqu'une certaine tâche matérielle a été effectuée et que le processeur / système d'exploitation devait être averti afin qu'ils puissent le traiter correctement (lecture des données du disque dans la mémoire, puis notification qu'il est prêt pour que nous puissions revenir). contrôle de l'application et lui permettre de le traiter), donc je ne sais pas ce que vous voulez dire et simplement mal interprété.
AturSams
2

Réponse à la question réelle (une boucle de jeu doit-elle être dans un thread séparé):

La raison pour laquelle les gens recommandent souvent d'utiliser un thread séparé est parce qu'ils ne veulent pas qu'un traitement lourd interfère avec l'interactivité de l'interface utilisateur. Vous êtes le seul à savoir si un thread séparé est nécessaire pour votre jeu. Cela dépend entièrement du moteur et du framework si la boucle de jeu principale dans votre conception actuelle peut interférer avec le temps de réponse de l'interface utilisateur. Je pensais que vous supposez généralement que ce ne sera pas le cas (dans les petits projets), sauf si vous avez une raison de penser le contraire.

Une autre raison de conserver le code dans des threads séparés est de garder le code modulaire et simple. La combinaison de deux parties de code non liées peut souvent rendre le code moins lisible et maintenable à long terme.

Une boucle de jeu doit-elle s'exécuter sur son propre thread séparé? Peut-être. S'il y a un problème avec le temps de réponse ou le code et que vous avez besoin de plusieurs éléments d'interface utilisateur pour répondre indépendamment du traitement lourd ou si vous souhaitez simplement diviser le code en tâches spécifiques qui se produisent simultanément pour des raisons de conception, allez-y. Cependant, il est considéré comme une pratique de programmation avancée .

Un simple mais peut-être pas un bon exemple pour illustrer est un jeu à deux joueurs. Vous souhaiterez peut-être exécuter deux instances d'une classe qui gèrent les entrées utilisateur et se convertissent en changements d'état dans l'instance de personnage du joueur.

Certains frameworks vous encouragent / vous obligent à utiliser un système basé sur les événements / interruptions comme ActionScript3.0. Dans ces cas, le code de boucle ira normalement à l' OnEnterFrameévénement ou quelque chose de similaire qui se produit 20 à 60 ou 120 fois par seconde.


Réponse à la question d'origine (ai-je besoin d'une boucle principale):

Tout se résume au compteur de programme . Si vous créez un jeu qui fonctionnera plus d'une durée prédéterminée et ne générera pas de code au fur et à mesure, vous devrez demander au PC de votre utilisateur de répéter certaines instructions qu'il a déjà traitées et ce qui changera éventuellement dans le entre-temps est l'état (les valeurs stockées dans les objets et les globaux du jeu).

Comme vous savez que vous devrez répéter les instructions, il existe plusieurs façons de terminer cette tâche et de traiter en permanence les mêmes instructions. Toutes ces méthodes impliquent de ramener le compteur de programme à l'instruction actuellement pertinente. Les instructions de flux de contrôle les plus courantes qui provoquent la répétition du code sont appelées boucles, une autre est l' gotoinstruction qui est rarement utilisée dans le code moderne et a un effet similaire dans ce cas (complètement sans rapport avec vous).

Donc, pour répondre à votre question précédente, avez-vous besoin d'une boucle? Oui.

AturSams
la source
1
Pour autant que je sache, les frameworks basés sur les événements, comme AS3, ont toujours une boucle de jeu en dessous. Je parle d'interruptions de niveau inférieur, pas d'un cadre qui implémente un système d'événements.
MichaelHouse
Hmm .. Je ne pense pas que les gens utilisent souvent des interruptions de niveau inférieur dans les jeux. AFAIK, ils sont principalement utilisés par le CPU pour surveiller les opérations d'E / S. Je pensais à une abstraction de niveau supérieur comme une pratique de conception où vous répondez aux entrées de l'utilisateur ou à l'activité matérielle (sans interrogation) plutôt que d'exécuter plusieurs instructions à chaque image, puis de dire au matériel de restituer le résultat.
AturSams
1
Oui, les gens ne les utilisent plus souvent. Comme je l'ai dit, ils sont plus difficiles à utiliser et nous avons maintenant de bien meilleures façons de faire les choses. Je comprends ce que vous dites, et c'est certainement une façon différente de penser les choses, mais ce n'est qu'en surface que cela semble différent, en dessous c'est le même type de boucle.
MichaelHouse
Je suis d'accord avec @ Byte56, cela se résume à une boucle, à moins que nous ne parlions d'événements au niveau du noyau qui utilisent des interruptions d'E / S.
concept3d
1
Je le sais mais la plupart de tout ce que nous faisons est le même sous la surface (comme je l'ai dit, en changeant la valeur du compteur de programme). Ce n'est pas un secret et je l'ai souligné dans la réponse. La programmation basée sur les événements est apparemment différente parce que nous déplaçons le compteur de programme vers différentes fonctions lorsque différents événements se produisent. Évidemment, il y a probablement une interrogation en boucle pour vérifier si ces événements se sont récemment produits, mais en tant que principe de conception, il est apparemment différent.
AturSams
0

Juste pour ajouter aux réponses d'autres personnes ici, quelque chose que personne n'a explicitement mentionné: si vous prenez le risque d'exécuter votre boucle de jeu dans un deuxième thread et qu'elle ne répond plus, vous risquez que le système d'exploitation termine votre application. C'est pourquoi il est recommandé d'utiliser un thread séparé. Par conséquent (par exemple) le NDK native_app_glue.c/ .hgénère un thread séparé pour votre boucle.

Ingénieur
la source