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

Graphisme Java Discussion :

[Stratégie]Boucle d'animation en Java


Sujet :

Graphisme Java

  1. #1
    Invité
    Invité(e)
    Par défaut [Stratégie]Boucle d'animation en Java
    Bonjour,

    Je voudrais créer une boucle d'animation en Java pour des animations 2D.

    C'est à dire :

    tous les delta temps faire {
    calculer les nouvelles positions de l'animation
    afficher l'animation
    }

    Il faut bien sûr que le temps d'exécution de "calculer les nouvelles positions de l'animation" + "afficher l'animation soit inférieur" à delta temps

    Vous auriez une piste efficace à m'indiquer pour réaliser cet algorithme ?

    Merci.
    [ Modéré par vedaer ]
    -> Ajout du tag dans le titre
    [ Merci de respecter les Règles du Forum ]

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2003
    Messages : 7
    Par défaut Précision
    Salut alors la chose la plus courante est de représenté logiquement les objets contenu dans ton animatoin par une classe ou une interface.

    Par ex une interface Moveable .
    contenant une méthode move(float deltaT);

    Chaque objet moveable devra implémenté la méthode move-->polymorphisme.
    Ensuite tu itérera sur tout les Moveable de ton monde pour appeler la méthode move sur chacun des objets de l'animation.Qui auront comme particularité commune, implements Moveable,
    Une fois l'animation recalculé tu n'as plus qu'à afficher chaque élément
    par exemple en utilisant une interface "Drawable", tu itérera sur chaque objet de ton animation.

    Il va de soit que ces interface c'est toi qui va les définir.


    PS: A l'avenir pourrait tu être un poil plus précis ça peut aider à te répondre de manière plus rapide et surtout plus précise....

    Salutation


  3. #3
    Membre expérimenté
    Avatar de JHelp
    Inscrit en
    Octobre 2002
    Messages
    185
    Détails du profil
    Informations forums :
    Inscription : Octobre 2002
    Messages : 185
    Par défaut Re: Boucle d'animation en Java
    Citation Envoyé par Kaji
    tous les delta temps faire {
    calculer les nouvelles positions de l'animation
    afficher l'animation
    }
    Ca tu peux le faire avec un Timer, cf FAQ
    Citation Envoyé par Kaji

    Il faut bien sûr que le temps d'exécution de "calculer les nouvelles positions de l'animation" + "afficher l'animation soit inférieur" à delta temps
    ca c'est moins simple à garantir, ca dépend de ton calcul, de ce que tu a afficher. La il faut optimiser au maximum l'affichage et le calcul. Ca depend aussi de ton laps de temps.
    Autrement si tu veux t'assurer que t'a boucle soit terminée avant un nouvel affichage, autre soulution que le timer, le thread perso, par exemple :

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    public class MaClasse implements Runnable
    {
           private Thread thread;
           private long lapsDeTemps = 1000; //en millisencondes, ici une seconde
           public MaClasse()
           {
           }
           public void lancerAnimation()
           {
               if(this.thread!=null)
               {
                    this.thread=newThread(this);
                    this.thread.start();
               }
            }
          public void run()
            {
                  while(true)
                  {
                       long temps = System.currentTimeMillis();
                       //calcul des positions
                       //nouvel affichage
                      long tps = System.currentTimeMillis();
                      long reste = lapsTemps - (tps-temps);
                      if(reste>0)
                      {
                          try
                          {
                              Thread.sleep(reste);
                          }
                          catch(Exception e)
                          {
                          }
                      }
                  }
           }
    //......
    }
    Ce la t'assure que ton animation ne se fera qu'au plus tôt tous les lapsTemps. Mais ça peut durer plus longtemps. Mais au moins tu es sur que ta boucle se terminera avant un nouvel affichage, pas de soucis de double affichage par exemple
    JHelp

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 95
    Par défaut
    tous les delta temps faire {
    calculer les nouvelles positions de l'animation
    afficher l'animation
    }
    Non, à éviter. Faire un boucle tous les "delta temps" est peut-être une solution simple, mais ne te donnera pas de résultat satisfaisant. Soit ton delta t est trop grand, dans ce cas, tu perds en fuidité inutilement, soit delta t est trop petit, et là, ça risque de faire n'importe quoi. Je te conseille plutôt de faire en boucle ton animation, et de calculer ton delta_t dynamiquement, comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    initialiser t0
    tant que le jeu continue, faire {
      t1 = prendre le temps
      delta_t = t1 - t0
     
      calculer les nouvelles positions de l'animation, en fonction de delta_t
      afficher l'animation
     
      t0 = t1
    }
    Crois-moi, ce n'est pas qu'un simple détail. Ca rejoint un peu l'idée de JHelp, sauf que je ne vois pas à quoi sert de "boucler dans le vide" inutilement (sauf dans le cas où tu imposes un taux de rafraichissement fixe).

  5. #5
    Invité
    Invité(e)
    Par défaut Ma solution actuelle
    Actuellement j'utilise un composant timer proposé par NetBeans.
    Ma solution actuelle donne ceci :
    C'est bon ? Ca ne perd pas trop de temps ?

    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
    18
    19
    20
    21
    22
    23
     
        ...
        private netbeans.examples.lib.timerbean.Timer timerAnimation;
     
        private void initComponents() {
            timerAnimation = new netbeans.examples.lib.timerbean.Timer();
            ...
            timerAnimation.setDelay(10L);
            timerAnimation.addTimerListener(new netbeans.examples.lib.timerbean.TimerListener() {
                public void onTime(java.awt.event.ActionEvent evt) {
                    timerAnimationOnTime(evt);
                }
            });
        }
     
     
    /** Calcule et affiche un pas de l'animation */
        private void timerAnimationOnTime(java.awt.event.ActionEvent evt) {
            // Add your handling code here:
            animation.calculerNouvellePosition();
            animation.effacerAnciennePosition();
            animation.afficherNouvellePosition();     
        }

    Et le code du Timer NetBeans est le suivant :

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
     
    /** The Timer JavaBean is a nonvisual component that sends an ActionEvent
    * to the registered TimerListeners every "delay" property milliseconds.
    * It can either send that event only once, or it can cycle (according to
    * the "onceOnly" property).
    *
    * @version  1.01, Sep 02, 1998
    */
    public class Timer extends Object
        implements java.io.Serializable {
     
        public static final String PROP_ONCE_ONLY = "onceOnly";
        public static final String PROP_DELAY = "delay";
     
        public static final long DEFAULT_DELAY = 1000;
        public static final boolean DEFAULT_ONLY_ONCE = false;
     
        static final long serialVersionUID =-7954930904657028678L;
     
        /** Creates a new Timer */
        public Timer() {
            delay = DEFAULT_DELAY;
            onceOnly = DEFAULT_ONLY_ONCE;
            propertySupport = new PropertyChangeSupport(this);
        }
     
        public synchronized void start() {
            if (running) return;
            timerThread = new TimerThread();
            running = true;
            timerThread.start();
        }
     
        public synchronized void stop() {
            if (!running) return;
            timerThread.stop();
            timerThread = null;
            running = false;
        }
     
        /** Getter method for the delay property.
        * @return Current delay value
        */
        public long getDelay() {
            return delay;
        }
     
        /** Setter method for the delay property.
        * @param value New delay value
        */
        public void setDelay(long value) {
            if (delay == value) return;
            long oldValue = delay;
            delay = value;
            propertySupport.firePropertyChange(PROP_DELAY,
                                               new Long(oldValue),
                                               new Long(delay));
        }
     
        /** Getter method for the onceOnly property.
        * @return Current onceOnly value
        */
        public boolean getOnceOnly() {
            return onceOnly;
        }
     
        /** Setter method for the onceOnly property.
        * @param value New onceOnly value
        */
        public void setOnceOnly(boolean value) {
            if (onceOnly == value) return;
            onceOnly = value;
            propertySupport.firePropertyChange(PROP_ONCE_ONLY,
                                               !onceOnly ? Boolean.TRUE : Boolean.FALSE,
                                               onceOnly ? Boolean.TRUE : Boolean.FALSE);
        }
     
        public void addPropertyChangeListener(PropertyChangeListener l) {
            propertySupport.addPropertyChangeListener(l);
        }
     
        public void removePropertyChangeListener(PropertyChangeListener l) {
            propertySupport.removePropertyChangeListener(l);
        }
     
        public void addTimerListener(TimerListener l) {
            if (listeners == null)
                listeners = new Vector();
     
            listeners.addElement(l);
        }
     
        public void removeTimerListener(TimerListener l) {
            if (listeners == null)
                return;
            listeners.removeElement(l);
        }
     
        private void fireTimerEvent() {
            if (listeners == null) return;
            Vector l;
            synchronized (this) {
                l = (Vector)listeners.clone();
            }
     
            for (Enumeration e = l.elements(); e.hasMoreElements();) {
                TimerListener tl = (TimerListener) e.nextElement();
                tl.onTime(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "onTime"));
            }
     
        }
     
        class TimerThread extends Thread {
            public void run() {
                while (true) {
                    try {
                        sleep(delay);
                    } catch (InterruptedException e) {}
                    fireTimerEvent();
                    if (onceOnly) break;
                }
                running = false;
            }
        }
     
        transient private TimerThread timerThread;
     
        /** The timer listeners */
        transient private Vector listeners;
     
        /** The support for firing property changes */
        private PropertyChangeSupport propertySupport;
     
        /** The flag indicating whether the timer is running */
        private boolean running;
     
        /** If true, the timer stops after firing the first onTime, if false
        * it keeps ticking until stopped */
        private boolean onceOnly;
     
        /** Delay in milliseconds */
        private long delay;
    }

    Il y a moyen de gagner beaucoup de temps ?

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 95
    Par défaut
    Il y a moyen de gagner beaucoup de temps ?
    Je me suis déjà bien exprimé sur ce sujet. Selon ce que tu veux faire, ça peut être suffisant. Maintenant, si tu es capable de calculer ton animation avec un delta_t variable et si tu as une problématique d'optimisation du code, alors je te conseille de regarder de plus près ce que je t'ai donné. Et encore, il est possible d'aller beaucoup plus loin. Si ça t'intéresse, je peux essayer de te donner quelques pistes.

  7. #7
    Membre éprouvé
    Avatar de narkotik
    Inscrit en
    Mai 2004
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 117
    Par défaut
    pour une boucle d'animation en java tu fais ca:

    une class pour la JFrame avec tout ce qu'il y a de dessiné ou d'écrit dans ta méthode paint() de ton composant.

    une class pour un thread qui toutes les x millisecondes appelle repaint() de ta JFrame

    pourquoi faire compliqué quand on peut faire simple et ultra-optimisé? 8)

  8. #8
    Invité
    Invité(e)
    Par défaut Simplicité
    Effectivement, Narcotik, je suis de ton avis. Je cherche à réaliser quelque chose de simple.

    Pour une animation il me semble obligatoire d'opter pour un rafraichissement à intervalles réguliers.

    Actuellement, j'ai utilisé le Timer fourni en exemple par l'EDI Netbeans. Je pense que je pourrais simplifier le timer fourni par NetBeans, comme tu le proposes Natcotik :

    une class pour un thread qui toutes les x millisecondes appelle repaint() de ta JFrame
    (Pour moi, ce sera un JPanel).

    J'essaye de réaliser un "Player d'animations". Grosso-modo, dans mon JFrame j'ai deux JPanels. Un pour les commandes des animations (JButtons, etc.) et un autre pour dessiner les animations.

    Je cherche à réaliser une sorte de petit support générique pour pouvoir ajouter facilement des animations sans tout redévelopper à chaque fois...

    Pour l'instant, je n'en suis qu'au stade apprentissage.

    Merci pour tous vos conseils en tous cas (pour le sujet "Affichage 2D rapide aussi) !

  9. #9
    Membre éprouvé
    Avatar de narkotik
    Inscrit en
    Mai 2004
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 117
    Par défaut
    pas de probleme kaji ca fait toujours plaisir d'aider

    par contre détrompes toi le rafraichissement n'a pas besoin d'etre régulier, en fait tout dépend de ta maniere de développer, par exemple, tu as pu remarquer que dans un quake-like, le nombre de fps varie et donc ton taux de rafraichissement varie mais c'est sur que si tu fixes une vitesse de rafraichissement c'est plus facile pour commencer a développer cependant apres tu es dépendant de ce temps pour toutes tes animations et ca c'est moins cool quand on y réfléchi bien.

    j'ai fait un tuto ici pour expliquer comment faire un rafraichissement optimisé, rapide avec un temps que tu peux changer facilement, à toi de l'adapter pour un JPanel mais ca devrait pas te poser de probleme
    http://java.developpez.com/sources/?...feringHardware

  10. #10
    Membre chevronné
    Avatar de Glob
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Avril 2002
    Messages
    428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Avril 2002
    Messages : 428
    Par défaut
    Lut,
    ma boucle:
    var startTime = currentTime
    while(jeuContinue) {
    // on calcule le temps écoulé depuis la dernière itération
    var elapsedTime = currentTime - startTime
    time = currentTime
    // on fait "vivre" le jeu pour le temps écoulé
    // le temps écoulé est utilisé pour bouger les objets en fonction de leur vitesse
    runAIAndPhysicsFor(elapsedTime)
    // on affiche l'état du jeu
    refreshDisplay()
    }
    -> pas besoin de multiplier les threads pour chaque "objet"
    -> pas de risque de recommencer un affichage alors que le précédent est en pas fini
    -> pas de risque de perturber le dessin par des calculs physiques ou AI: c'est chacun son tour...
    -> inutile de s'inquiéter de synchronisation (accès simultané aux objets par la vue et le controlleur/modèle), qui peut être coûteuse...
    -> Java ne "perd" pas de temps à passer d'un Thread à l'autre


  11. #11
    Membre éclairé Avatar de soad
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    520
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2004
    Messages : 520
    Par défaut
    pour faire un petit jeu 2D il existe une bibliothèque qui s'appelle JADE !!! J'avou ne jamais l'avoir utilisé mais ca ma l'aire pas mal du tout

    voici un liens pour ceux que ca intéresse http://jade.pautrot.com/accueil.php

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Animation en java
    Par Mo_Poly dans le forum 2D
    Réponses: 5
    Dernier message: 01/03/2007, 18h04
  2. Animation sous Java
    Par f2001 dans le forum Applets
    Réponses: 13
    Dernier message: 19/08/2006, 19h05
  3. animation en java
    Par mwanjany dans le forum Langage
    Réponses: 3
    Dernier message: 10/04/2006, 13h20
  4. Afficher un gif animé en Java
    Par julio26 dans le forum 2D
    Réponses: 5
    Dernier message: 06/03/2006, 12h04
  5. [Stratégie] Afficher une animation dans un JScrollPane
    Par patmaba dans le forum AWT/Swing
    Réponses: 8
    Dernier message: 11/10/2005, 09h49

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