// import les package utilises import java.awt.* ; import java.util.* ; import java.applet.* ; // package personnel : objet graphique import packsprite.* ; /* objet pyramide2 * applet principale * optimisation du code : * - le maximum de clas sont declare final * - le code est compile avec option -O */ final public class pyramide2 extends Applet implements Runnable { /* declaration des variables */ // canvas animation protected animation anim ; // barre de defilement permettant de definir le nombre de rangee protected Scrollbar sb ; // nombre de rangee, par defaut 8 static int NbRangee = 8 ; // label indiquent le nombre de rangee visuellement pour l'utilisateur protected Label indicationNombreRangee ; private Thread threadGarbageCollector ; /* initialisation de l'applet */ public void init() { // sert a vider les objets de la memoires par appels recursifs de la methode vider jusqu'a ce que la memoire soit vide threadGarbageCollector = new Thread(this) ; threadGarbageCollector.start() ; // definit la couleur d'arriere plan setBackground(Color.white) ; // recupere du document HTML le nombre de rangee String nb = getParameter("nombre_rangee") ; if (nb != null) NbRangee = Integer.valueOf(nb).intValue() ; // cree un paneau de controle contenant tous les boutons utils a l'utilisateur Panel paneau1 = new Panel() ; paneau1.setBackground(Color.white) ; // bouton start permettant de demarrer une nouvelle animation paneau1.add(new Button("Start")) ; // bouton pause permettant de stoper momentanement une animation paneau1.add(new Button("Pause")) ; // bouton continue pour continue une animation deja debute paneau1.add(new Button("Continue")) ; // barre de defilement(nombre de rangee) : valeur max et min 2 et 16 sb = new Scrollbar(Scrollbar.HORIZONTAL, NbRangee, 2, 2, 16) ; paneau1.add(sb) ; // label definissant le nombre de rangee visuellement pour l'utilisateur indicationNombreRangee = new Label("n = "+Long.toString((long)sb.getValue())) ; paneau1.add(indicationNombreRangee) ; // ajoute a l'applet le paneau de controle et l'animation add("North", paneau1) ; anim = new animation() ; add("Center", anim) ; anim.demarrage(NbRangee) ; anim.actif = true ; } /* sert a vider les objets du Garbage collector methode bourrin mais qui marche tres bien */ public void run() { /* while(threadGarbageCollector!=null) { viderGC() ; try { threadGarbageCollector.sleep(20000) ; } catch (Exception e) {System.out.println(e);} } */ } /* sert a vider les objets du Garbage collector methode bourrin mais qui marche tres bien */ public static void viderGC() { Runtime rt = Runtime.getRuntime() ; long vide=rt.freeMemory() ; long aVide ; do { aVide=vide ; rt.gc() ; vide=rt.freeMemory() ; } while (vide>aVide) ; rt.runFinalization() ; } /* gere les evenements utilisateur */ public boolean handleEvent(Event e) { // si la barre de defilement est modifie... if (e.target instanceof Scrollbar) { // definit le label du nombre de range long nouveauNrangee = (long)(sb.getValue()/2)*2 ; indicationNombreRangee.setText("n = "+Long.toString(nouveauNrangee)) ; return true ; } // si un bouton est active... if (e.target instanceof Button) { if (e.id==Event.ACTION_EVENT) { // recupere le label du bouton active Button bt = (Button)e.target ; // gere le bt start if ("Start".equals(bt.getLabel())) { // recupere le nombre de rangee de la barre de defilement : un nombre paire NbRangee = (sb.getValue()/2)*2 ; // demarre l'animation anim.demarrage(NbRangee) ; anim.actif = true ; return true ; } // gere le bt pause if ("Pause".equals(bt.getLabel())) { // met l'animation inactif anim.actif = false ; } // gere le bt continue if ("Continue".equals(bt.getLabel())) { // met l'animaiton actif anim.actif = true ; } } } return false ; } } final class animation extends packsprite.spritecanvas { /* declaration des variables */ // objet directeurs private directeurpiquets dp ; private directeurballes db ; private directeurbarres dbarres ; // objet qui trace le graphique private tracergraph trace ; // nombre de rangee de piquet private int NbRangee ; // espacement entre les piquets private int intervallePiquet = 20 ; // image de la courbe gaussienne et des piquets private Image imageGaussienne = null ; // position horizontale du texte du compteur du nombre de tirage private int posHcompteurTirage ; /* createur objet animation */ public animation() { // redimentionne le canvas resize(370, 370) ; // temps de rafraichissement delai = 33 ; // definit une couleur d'arriere plan setBackground(Color.white) ; start() ; } /* demmare une nouvelle animation */ public void demarrage(int NbRangee) { this.NbRangee = NbRangee ; // creer une image hors ecran imageGaussienne = createImage(size().width, size().height) ; // obtient le graphics de l'image creee precedement Graphics gg = imageGaussienne.getGraphics() ; // dessine le fond gg.setColor(getBackground()) ; gg.fillRect(0,0,size().width,size().height) ; // dessine la gaussienne sur l'image hors ecran trace = new tracergraph(size(), NbRangee) ; trace.paint(gg) ; // definit l'espacement entre les piquets : // la valeur 280 represente une echelle fixe intervallePiquet = 280/NbRangee ; // cree les directeurs des balles, barre et piquet db = new directeurballes(this, intervallePiquet) ; dbarres = new directeurbarres(this, NbRangee, intervallePiquet, db.getTableauBalles()) ; dp = new directeurpiquets(this, NbRangee, intervallePiquet, db.getTableauBalles()) ; // dessine les piquet sur l'image hors ecran dp.paint(gg) ; // dessine le contour de l'animation avec une bordure noir sur l'image hors ecran gg.setColor(Color.black) ; gg.drawRect(0,0,size().width-1, size().height-1) ; // dessine la phrase suivante : String phraseNbTirage = "Number of experiments : " ; gg.setFont(new Font("Times", Font.PLAIN, 12)) ; gg.drawString(phraseNbTirage, 3, 30) ; // calcul la position horizontale du compteur du nombre de tirage FontMetrics fm = gg.getFontMetrics() ; posHcompteurTirage = fm.stringWidth(phraseNbTirage) ; } /* dessine tous les objets graphique de l'animation */ public void paint(Graphics g) { // dessine le fond if (imageGaussienne!=null) g.drawImage(imageGaussienne, 0, 0, this) ; // mise a jour des piquets if (dp!=null) dp.update() ; // dessine dans l'ordre les barres puis les balles if (dbarres!=null) { // inscrit le nb de tirages g.setColor(Color.black) ; g.drawString(Long.toString((long)dbarres.N), posHcompteurTirage, 30) ; // dessine les barres dbarres.paint(g) ; } // dessine les balles if (db!=null) db.paint(g) ; } } /* objet directeur des piquets */ final class directeurpiquets { // vecteur contenant tous les objets piquets private Vector vecteurPiquet ; /* contructeur des piquets */ public directeurpiquets(Canvas parent, // canvas parent int NbRangee, // nombre de rangee int intervallePiquet, // espacement entre les piquets collisionsprite[] collis) { // tableau contenant les objets balles // initialisation des variables vecteurPiquet = new Vector() ; // creer les piquets for (int j=0 ; j<=NbRangee ; j++) { for (int i=0 ; i15) creerBalle() ; // pour chaque balle... for (int i=0 ; i=x) && (pos.x<=(x+w)) && (pos.y+grand.h>=y) && (pos.y<=(y+h))) { return true ; } else { return false ; } } /**** IMPLEMENTS BOUGER ****/ /* mise a jour position de la balle */ public void updatePosition() { // au debut vitesse horizontale = 0 donc faible acceleration if (vit.vH!=0) setVitesse(vit.vH, vit.vV+0.5) ; else setVitesse(vit.vH, vit.vV+0.3) ; // nouvelle position de la balle setPosition(pos.x+vit.vH, pos.y+vit.vV) ; } /* definit une nouvelle position pour la balle */ public void setPosition(double x, // nouvelle position horizontale double y) { // nouvelle position verticale pos.x = x ; pos.y = y ; } /* definit une nouvelle vitesse pour la balle */ public void setVitesse(double vH, // nouvelle vitesse horizontale double vV) { // nouvelle vitesse verticale vit.vH = vH ; vit.vV = vV ; } /**** implement collisionsprite ****/ // renvoie la postion public position getPosition() { return pos ; } /* renvoie la vitesse */ public vitesse getVitesse() { return vit ; } /* renvoie la taille */ public grandeur getGrandeur() { return grand ; } /* definit une taille */ public void setGrandeur(double w, // nouvelle taille horizontale double h) { // nouvelle taille verticale grand.w = w ; grand.h = h ; } } /* directeur barres */ final class directeurbarres { /* declaration des variables */ // vecteur contenant tous les objets barres protected Vector vecteurBarres ; // taille du canvas contenant l'animation protected Canvas parent ; // nombre de tirage protected double N = 0 ; /* constructeur des barres */ public directeurbarres(Canvas parent, // canvas parent int NbRangee, // nombre de rangee int esp, // taille horizontale des barres collisionsprite[] tabBalles) { // tableau contenant les pointeurs sur toutes les balles this.parent = parent ; vecteurBarres = new Vector() ; int droite = 0 ; int gauche = 0 ; // creer toutes les barres for (int i=0 ; i<=NbRangee ; i++) { // determine la position gauche de la barre gauche = (int)(((double)parent.size().width/2) + (((double)esp/2)*((double)NbRangee-1)) - ((double)i*(double)esp)) ; // puis sa position droite droite = gauche + esp ; // cree une nouvelle barre vecteurBarres.addElement(new barre(gauche, 10000, esp, 200, parent, droite, gauche, NbRangee+1, this, tabBalles)) ; } } /* dessine toutes les barres */ public void paint(Graphics g) { for (int i=0 ; i parent.size().height) { // verifie si une balle est entre l'intervalle de la barre if ((balleCourante.getPosition().x>gauche) && (balleCourante.getPosition().x