Animation

molezi0 Messages postés 2 Date d'inscription samedi 3 janvier 2004 Statut Membre Dernière intervention 15 janvier 2004 - 6 janv. 2004 à 20:41
cs_doudouseb Messages postés 1 Date d'inscription vendredi 13 février 2004 Statut Membre Dernière intervention 13 février 2004 - 13 févr. 2004 à 09:09
Bonjour , ca serai sympa d'aider un débutant en java !! (désolé c'est un peu long)
La structure de mon animation est :
class ??? extends JFrame implements Runnable,WindowListener
{ Thread t ;
Image I ;
Graphics G;

???()
{ t=new Thread(this);
t.start();
}

void run()
{ while(???)
{ .......
......
......
try{t.sleep(30);}catch(Exception e){}
repaint();
}
}

void paint(Graphics g)`
{ G.draw......
...............
...............
g.drawImage(I,0,0,this);
}

void windowOpened(WindowEvent e){ I=createImage(......)}
....................................
....................................
....................................
}

Cette animation fonctione correectement seulement malgré le méthode du double Buffering l'image n'est pas parfaitement fluide .Pourtant la thread doit s'executer toutes les 30ms ce qui correspond à 33 images par seconde c'est même plus rapide qu'au cinéma.
J'ai d'abord pensé que le temps d'éxecution de ma boucle + le temps d'éxecution de paint n'était en fait pas négligeable (comme je le suppose ici). J'ai donc rajouté un compteur de temps :
class timeCounter
{ long a,b;

timeCounter()
{ restart();
}

void restart()
{ a=System.currentTimeMillis();
}

long getTime()
{ return System.currentTimeMillis()-a;
}
}

Mon api s'écrit donc :
class ??? extends JFrame implements Runnable,WindowListener
{ Thread t ;
Image I ;
Graphics G;
timeCounter tc;

???()
{ t=new Thread(this);
t.start();tc=new timeCounter();
}

void run()
{ while(???)
{ tc.restart();
.......
......
......
try{t.sleep(30-tc.getTime());}catch(Exception e){}
repaint();
}
}

void paint(Graphics g)
{ G.draw......
...............
...............
g.drawImage(I,0,0,this);
}

void windowOpened(WindowEvent e){ I=createImage(......)}
....................................
....................................
....................................
}

Mais ça change rien.
Alors j'ai fait afficher les temps entre chaque appel à restart , j'ai donc placé :

try{t.sleep(30-tc.getTime());}catch(Exception e){}
repaint();
System.out.println("" + tc.getTime());

Et j'obtient des séries du style :
0
0
50
0
60
Ce qui semble expliquer mon problème.

Mais pour tester la methode currentTimeMillis j'ai essayé dans une autre api le programme suivant:

int i ,n=??;
timeCounter tc = new timeCounter()
for(i=0;i<=n;i++)
{ quelquechose de pas long à effectuer
}
System.out.println("" + tc.getTime());

Avec n petit on trouve bien sur 0.
Mais ensuite pour n grand on passe directement d'un temps d'execution nul à 50ms pour n une peu plus grand.
Par ex:n=10000=>tc.getTime()=0
n=11000=>tc.getTime()=50 // on remarque les même 50ms de tout à l'heure
Et je n'arrive pas à passer au dessous de 50ms alors que le temps d'execution T=f(n) est très proche d'une fonction linéaire.
J'en conclut que c'est la méthode currentTimeMillis() qui n'est pas assez précise!
Le fait de modifier mon programme :
try{t.sleep(30-tc.getTime());}catch(Exception e){}
repaint();
ne sert donc a rien vu que l'incertitude sur tc.getTime() est trop grande , on ne peut pas ajuster le temps d'attente de la thread de cette façon.
Et je ne sais plus ou j'en suis , les mesures sur le temps d'execution de la boucle de mon animation ne sont pas valide et je ne sais pas si le temps d'execution est irrégulier.

En conclusion : Est-ce que la méthode sleep(t) est bien fiable(le temps t est-il garanti ou est -ce un temps d'attente "en moyenne"?)
si oui pourquoi mon animation n'est pas totalement fluide ?
si non comment puis-je faire une animation bien fluide?

Désolé c'est un peu long mais c'était pour bien présenter le problème dans son ensemble.

2 réponses

nicowatt Messages postés 74 Date d'inscription mercredi 15 janvier 2003 Statut Membre Dernière intervention 18 janvier 2013
7 janv. 2004 à 14:42
A vrai dire j'ai eu un peu la flème de tout lire ! (dsl !) ;-)
Mais si tu veux faire de l'animation pure, utilise l'api JAVA3D, elle sera très satisfaisante pour tes besoins...

NicoWatt...
0
cs_doudouseb Messages postés 1 Date d'inscription vendredi 13 février 2004 Statut Membre Dernière intervention 13 février 2004
13 févr. 2004 à 09:09
Bonjour,

J'ai exactement le même problème, c'est à dire une animation saccadée à cause d'une série de temps non homogènes 1 1 150 1 0 2 120 ... alors que le traitement en lui même ne dépasse pas 2ms.

Pour moi, je verrais plutot le fait d'une gestion des thread par la machine virtuelle. C'est à dire que je suppose que le thread perd la main et ne la récupère que quelques ms plus tard(en dehors de l'effet du sleep), ce qui fausse tout le timing de l'animation.

Je vais essayer de mettre la priorité du thread au maximum. Peut-être que dans ce cas il ne sera jamais interrompu.
Je te tiens au courant si ça marche.

As-tu essayé l'API java3d? Est-ce que le problème a été résolu grace elle?
0
Rejoignez-nous