IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement 2D, 3D et Jeux Discussion :

Timers, boucles d'affichage et Thread.sleep


Sujet :

Développement 2D, 3D et Jeux

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut Timers, boucles d'affichage et Thread.sleep
    Salut!

    Je suis en train d'apprendre 2-3 trucs par ci par là pour faire un jeu "2D" (2D entre guillemets car il y aura une bonne gestion de la profondeur, mais bon techniquement ça reste de la 2D). Dans ce jeu le timing est très important puisqu'en plus de gérer l'affichage général comme dans beaucoup de jeux, il gèrera en bonne part les actions de chaque créature.

    Donc j'ai besoin d'un timer aussi précis et régulier que possible... System.nanoTime() à l'air convenable, seulement j'ai un problème avec Thread.sleep(long ms). Si je veux faire un sleep de 10 millisecondes par exemple, il me sort souvent un écart de 5 millisecondes, soit 15 au lieu de 10!
    Parfois c'est 17, parfois 12 ou même (si si!) 10. Un tel écart à chaque nouvelle boucle (le sleep est en fin de boucle while) ça doit vite fausser tout le truc j'imagine.

    Bref, y a-t-il un moyen plus précis de faire pause sur le thread ?
    J'ai essayé Thread.yield dans une "sous-boucle" while à l'intérieur de la boucle principale.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while(TempsPasséInférieurA10Millisecondes) {
     Thread.yield();
    }
    ça marche bien évidemment, mais ça bouffe tout mon CPU... D'accord, des ressources CPU sont relachées quand un autre programme en a besoin mais j'aimerai autant trouver un autre moyen que de mettre mon processeur en surchauffe constante juste pour un timer. Surtout qu'en relachant des ressources pour d'autres programmes, ça peut rendre la vitesse d'affichage du jeu irrégulière...


    Donc, y a-til une technique particulière pour pallier à l'imprécision de Thread.sleep ?

    Merci!

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Les OS actuels allouent plusieurs dizaines de millisecondes par processus (si je me souviens bien c'est de l'ordre de 50 ms pour Linux), alors espérer endormir un processus avec une précision de l'ordre de la milliseconde, c'est mission impossible.

    En même temps, un jeu qui ne tolère pas plus d'écart, ça paraît bizarre. Normalement ce n'est pas un souci.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut
    Ok, si les grands jeux s'en sortent avec cette imprécision je devrais pouvoir survivre aussi. >>

    Je pensais qu'ils avaient des timers très précis en fait, j'avais lu quelques posts et tutoriaux où la grande précision des timers semblait limite acquise et ça me paraissait crédible, je voyais pas un jeu comme Baldur's Gate II se contenter d'approximations. Mais bon vu ce que tu m'as dit à propos des OS, la grande précision a l'air impossible sans un truc qui prend toutes les ressources CPU (comme une boucle while avec Thread.yield)...

    Tant que BG2 et compagnie s'en sortent ça me va. Merci!

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut
    Toujours le même sujet; ma boucle d'affichage ne tourne qu'à 64 images par seconde. J'ai cru comprendre en lisant ici et là sur le net, que les développeurs aimaient viser les 100 images par seconde. Y a-t-il une différence notable de qualité ? L'oeil humain ne perçoit que 24 images par seconde il me semble, mais d'un autre côté 24 IPS ça se voit nettement que c'est moins bien que 50 ou 60. Donc peut-être que 100 est encore plus fluide. Si 100 est le "standard" d'aujourd'hui (mais l'est-ce ?), autant m'y plier.
    On en revient donc à ce problème de Thread.sleep car c'est lui qui me bloque à 64. (Je monte bien au dessus avec Thread.yield mais il crame mon CPU donc bon)

    Vous tous qui avez une certaine expérience là dedans, comment faites-vous ? Comment sont vos boucles d'affichage ? (Je précise que je suis en Java)
    ------------------------------------------------------------------------------------------------------------------------
    Autre question vite fait: quels sont les avantages et inconvénients d'utiliser plusieurs threads pour un jeu ?

    N'est-ce pas mieux d'utiliser un seul thread ? Dans quelles circonstances le multi-threading est il bénéfique ? (mon but étant un jeu 2D assez avancé quand même, je suis encore loin de pouvoir le faire mais l'apprentissage avance)

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    100 images par seconde n'est absolument pas un standard. Pour les Quake-like (les jeux qui bougent dans tous les sens), 60 est un minimum pour ne pas noter de saccades, sinon on peut même viser un peu moins.

    Si tu veux le même framerate sur toutes les machines il faut endormir ton application un peu à chaque tour de boucle ; c'est effectivement pas très précis mais j'ai rarement vu un jeu auquel ça posait poblème.

    Si tu veux un framerate constant mais qui peut varier un peu selon la machine, tu peux très simplement activer la synchronisation verticale.

  6. #6
    Membre actif
    Profil pro
    Étudiant
    Inscrit en
    Février 2005
    Messages
    263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2005
    Messages : 263
    Points : 255
    Points
    255
    Par défaut
    Pour avoir une pause qui soit en moyenne de 10 milisecondes, tu peux aussi regarder combien de temps le sleep() dure, et retirer le temps qui a été trop long au prochain wait...

    et ce que tu dois te demander, c'est si tu veux 100 images par secondes ou 100 'update' par secondes... en gros, voilà comment je fais (méthode prodiguée par "killer game programming in java", édité par O'Reilly). Je fais un update du jeu, je fais un rendu à l'écran, et j'attends le reste du temps afin d'obtenir une période de X millisecondes. Je regarde combien de temps le processus a réellement attendu, et je le retient pour le soustraire à X la prochaine fois...

    Et si tu veux doubler ton nombre d'update par boucle, tu n'as qu'à mettre 2 fois update() dans ta boucle (c'est pas top du tout, mais comme ça, si ton rendu est vraiment trop lent, ça accélère le jeu...)

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par Laurent Gomila
    100 images par seconde n'est absolument pas un standard. Pour les Quake-like (les jeux qui bougent dans tous les sens), 60 est un minimum pour ne pas noter de saccades, sinon on peut même viser un peu moins.

    Si tu veux le même framerate sur toutes les machines il faut endormir ton application un peu à chaque tour de boucle ; c'est effectivement pas très précis mais j'ai rarement vu un jeu auquel ça posait poblème.

    Si tu veux un framerate constant mais qui peut varier un peu selon la machine, tu peux très simplement activer la synchronisation verticale.
    D'accord ça devrait aller 64 alors, surtout que le jeu que je souhaite faire ne bouge pas dans tous les sens comme un Quake ou CS. La synchronisation verticale aurait pu etre intéressante mais apparemment, sur un écran 60Hz, si le framerate est inférieur à 60 il se synchronise à une fraction de 60 (comme 30), ce qui est quand même génant... Je vais utiliser Thread.sleep du coup.

    Pour avoir une pause qui soit en moyenne de 10 milisecondes, tu peux aussi regarder combien de temps le sleep() dure, et retirer le temps qui a été trop long au prochain wait...

    et ce que tu dois te demander, c'est si tu veux 100 images par secondes ou 100 'update' par secondes... en gros, voilà comment je fais (méthode prodiguée par "killer game programming in java", édité par O'Reilly). Je fais un update du jeu, je fais un rendu à l'écran, et j'attends le reste du temps afin d'obtenir une période de X millisecondes. Je regarde combien de temps le processus a réellement attendu, et je le retient pour le soustraire à X la prochaine fois...

    Et si tu veux doubler ton nombre d'update par boucle, tu n'as qu'à mettre 2 fois update() dans ta boucle (c'est pas top du tout, mais comme ça, si ton rendu est vraiment trop lent, ça accélère le jeu...)
    Les mises à jours des données du jeu sont incluses dans ma boucle oui, donc je parlais d'updates par seconde. Je vais essayer ta suggestion en tout cas.



    Merci pour votre aide! Je sais pas si vous avez vu ma dernière question donc je là remet au cas où:
    Quels sont les avantages et inconvénients d'utiliser plusieurs threads pour un jeu ?
    N'est-ce pas mieux d'utiliser un seul thread ? Dans quelles circonstances le multi-threading est il bénéfique ? (mon but étant un jeu 2D assez avancé quand même, je suis encore loin de pouvoir le faire mais l'apprentissage avance)


    Voilà ça ira après ça, j'arrête les questions...jusqu'à la prochaine fois

  8. #8
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut
    Cela m'interesse... Aurais-tu un exemple bidon de boucle d'affichage?

    Dans mon cas, j'ai des résultats catastrophiques (ordre de 90ms pour afficher chaque frame), et pourtant:
    - j'utilise le double buffering
    - je suis en mode plein écran...
    - je n'utilise pas JOGL

    De plus, ce résultat est obtenu avec quasiment aucun traitement! Mon image de fond est chargée au démarrage et pèse 130Ko. Mon animation comporte 12 frames, et chaque pèse moins d'un 1Ko...

  9. #9
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    Je ne veux pas troller mais tu parles de Baldur's Gate toi tu programmes en Java et avec Java je doute que cela soit possible d'avoir un jeu avec des performances de Baldur's Gate

    Citation Envoyé par Silk_do_Nadear
    Quels sont les avantages et inconvénients d'utiliser plusieurs threads pour un jeu ?
    N'est-ce pas mieux d'utiliser un seul thread ? Dans quelles circonstances le multi-threading est il bénéfique ? (mon but étant un jeu 2D assez avancé quand même, je suis encore loin de pouvoir le faire mais l'apprentissage avance)


    Voilà ça ira après ça, j'arrête les questions...jusqu'à la prochaine fois
    Faire une recherche sur le forum ce sujet a été déjà abordé maintes fois pour aller vers des discussions houleuses
    En gros si tu as un processeur dernière génération comme ceux d'Intel avec technologie hyperthreading dual core cela peut valoir le coup quoique pour ma part un peu sceptique quant au gain réel de performances ( ce qui n'empêche pas de faire des essais)
    La problèmatique : est-ce que Java utilise avec quintessence ces dernières techs..?

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut
    Billynirvana, pour un exemple de boucle d'affichage, même si je pense pas que ça t'aidera beaucoup...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    while(isActive)
    {
     
    // gestion input du joueur
     
    // mouvements, collisions, etc
     
    // rendu
     
    // si le temps passé dans ce loop 
    // est inférieur au temps "souhaité", 
    // Thread.sleep le reste du temps
    // Autrement un Thread.sleep(1)
    // pour être sûr de récupérer
    // les input proprement...
     
    }
    Tu devrais essayer de voir où est ce que tu perds le plus de temps. Si c'est ton Thread.sleep qui est aussi long... lis la réponse de Laurent Gomila plus haut. (Moi mon Thread.sleep prend en moyenne 12 millisecondes si je me souviens bien)
    Les OS actuels allouent plusieurs dizaines de millisecondes par processus (si je me souviens bien c'est de l'ordre de 50 ms pour Linux), alors espérer endormir un processus avec une précision de l'ordre de la milliseconde, c'est mission impossible.


    Mat.M... Je crois que Java est assez puissant pour ça, et sinon je ferais des compromis. J'ai vu une démo du moteur de Quake 3 porté en Java et il tournait tranquillement. Si Java supporte les appli 3D, Il devrait gérer un Baldur's Gate aussi
    Mais Baldur n'était qu'un exemple, car c'est un jeu où le timing est omniprésent, un peu comme dans mon futur jeu...

    Merci pour l'info sur les Threads, je pense que je vais rester en "single-thread" même si les thread java sont des threads légers qui mettent moins de temps à basculer de l'un à l'autre.

    Pour ce qui est des dernières techniques, moi je me contenterai des fonctions basiques d'OpenGL (ou meme pas d'OpenGL du tout je verrais), mais je sais pas si JOGL (Java OpenGL) est assez développé pour le moment...

  11. #11
    Membre actif Avatar de orelero
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    389
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 389
    Points : 274
    Points
    274
    Par défaut
    Citation Envoyé par Mat.M
    Je ne veux pas troller mais tu parles de Baldur's Gate toi tu programmes en Java et avec Java je doute que cela soit possible d'avoir un jeu avec des performances de Baldur's Gate
    Je ne sais pas si on peut comparer ce jeu: http://technopolies.net/ à baldur's gate mais ça montre qu'on peut faire quelque chose de vraiment correct en Java. En plus c'est un projet amateur en solo et il ne s'est jamais plein de manque de performence du langage.
    "L'imagination est plus importante que la connaissance." - Albert Einstein.

Discussions similaires

  1. Equivalent d'un thread.sleep à l'aide de timer
    Par lasrevinu dans le forum C#
    Réponses: 8
    Dernier message: 12/04/2010, 12h54
  2. Réponses: 5
    Dernier message: 03/03/2010, 13h27
  3. Réponses: 0
    Dernier message: 01/08/2008, 10h57
  4. JButton avec boucle while contenant thread.sleep(1000)
    Par v4np13 dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 17/10/2007, 20h31
  5. [Débutant][Thread] Comment lancer en boucle un affichage
    Par comme de bien entendu dans le forum Général Java
    Réponses: 6
    Dernier message: 03/02/2006, 10h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo