Séance 3

This commit is contained in:
Erwann PHILIPPE 2025-02-25 16:05:49 +01:00
parent f1168518e6
commit e6c955d51a
21 changed files with 1364 additions and 0 deletions

View file

@ -38,6 +38,10 @@ public class Joueur extends Objet {
*/
private Boule boule ;
private int vie;
private int orientation;
/**
* Constructeur
*/
@ -94,6 +98,11 @@ public class Joueur extends Objet {
public void perteVie() {
}
private Boolean toucheMur() {
return null;
}
/**
* vrai si la vie est à 0
* @return true si vie = 0

25
src/modele/Boule.java Normal file
View file

@ -0,0 +1,25 @@
package modele;
/**
* Gestion de la boule
*
*/
public class Boule extends Objet {
/**
* instance de JeuServeur pour la communication
*/
private JeuServeur jeuServeur ;
/**
* Constructeur
*/
public Boule() {
}
/**
* Tire d'une boule
*/
public void tireBoule() {
}
}

29
src/modele/Jeu.java Normal file
View file

@ -0,0 +1,29 @@
package modele;
/**
* Informations et méthodes communes aux jeux client et serveur
*
*/
public abstract class Jeu {
/**
* Réception d'une connexion (pour communiquer avec un ordinateur distant)
*/
public abstract void connexion() ;
/**
* Réception d'une information provenant de l'ordinateur distant
*/
public abstract void reception() ;
/**
* Déconnexion de l'ordinateur distant
*/
public abstract void deconnexion() ;
/**
* Envoi d'une information vers un ordinateur distant
*/
public void envoi() {
}
}

33
src/modele/JeuClient.java Normal file
View file

@ -0,0 +1,33 @@
package modele;
/**
* Gestion du jeu côté client
*
*/
public class JeuClient extends Jeu {
/**
* Controleur
*/
public JeuClient() {
}
@Override
public void connexion() {
}
@Override
public void reception() {
}
@Override
public void deconnexion() {
}
/**
* Envoi d'une information vers le serveur
* fais appel une fois à l'envoi dans la classe Jeu
*/
public void envoi() {
}
}

View file

@ -0,0 +1,50 @@
package modele;
import java.util.ArrayList;
/**
* Gestion du jeu côté serveur
*
*/
public class JeuServeur extends Jeu {
/**
* Collection de murs
*/
private ArrayList<Mur> lesMurs = new ArrayList<Mur>() ;
/**
* Collection de joueurs
*/
private ArrayList<Joueur> lesJoueurs = new ArrayList<Joueur>() ;
/**
* Constructeur
*/
public JeuServeur() {
}
@Override
public void connexion() {
}
@Override
public void reception() {
}
@Override
public void deconnexion() {
}
/**
* Envoi d'une information vers tous les clients
* fais appel plusieurs fois à l'envoi de la classe Jeu
*/
public void envoi() {
}
/**
* Génération des murs
*/
public void constructionMurs() {
}
}

128
src/modele/Joueur.java Normal file
View file

@ -0,0 +1,128 @@
package modele;
/**
* Gestion des joueurs
*
*/
public class Joueur extends Objet {
/**
* vie de départ pour tous les joueurs
*/
private static final int MAXVIE = 10 ;
/**
* gain de points de vie lors d'une attaque
*/
private static final int GAIN = 1 ;
/**
* perte de points de vie lors d'une attaque
*/
private static final int PERTE = 2 ;
/**
* pseudo saisi
*/
private String pseudo ;
/**
* n° correspondant au personnage (avatar) pour le fichier correspondant
*/
private int numPerso ;
/**
* instance de JeuServeur pour communiquer avec lui
*/
private JeuServeur jeuServeur ;
/**
* numéro d'<EFBFBD>tape dans l'animation (de la marche, touché ou mort)
*/
private int etape ;
/**
* la boule du joueur
*/
private Boule boule ;
/**
* vie restante du joueur
*/
private int vie ;
/**
* tourné vers la gauche (0) ou vers la droite (1)
*/
private int orientation ;
/**
* Constructeur
*/
public Joueur() {
}
/**
* Initialisation d'un joueur (pseudo et numéro, calcul de la 1ère position, affichage, création de la boule)
*/
public void initPerso() {
}
/**
* Calcul de la première position aléatoire du joueur (sans chevaucher un autre joueur ou un mur)
*/
private void premierePosition() {
}
/**
* Affiche le personnage et son message
*/
public void affiche() {
}
/**
* Gère une action reçue et qu'il faut afficher (déplacement, tire de boule...)
*/
public void action() {
}
/**
* Gère le déplacement du personnage
*/
private void deplace() {
}
/**
* Contrôle si le joueur touche un des autres joueurs
* @return true si deux joueurs se touchent
*/
private Boolean toucheJoueur() {
return null;
}
/**
* Gain de points de vie après avoir touché un joueur
*/
public void gainVie() {
}
/**
* Perte de points de vie après avoir été touché
*/
public void perteVie() {
}
/**
* Contrôle si le joueur touche un des murs
* @return true si un joueur touche un mur
*/
private Boolean toucheMur() {
return null;
}
/**
* vrai si la vie est à 0
* @return true si vie = 0
*/
public Boolean estMort() {
return null;
}
/**
* Le joueur se déconnecte et disparait
*/
public void departJoueur() {
}
}

14
src/modele/Mur.java Normal file
View file

@ -0,0 +1,14 @@
package modele;
/**
* Gestion des murs
*
*/
public class Mur extends Objet {
/**
* Constructeur
*/
public Mur() {
}
}

27
src/modele/Objet.java Normal file
View file

@ -0,0 +1,27 @@
package modele;
/**
* Informations communes <EFBFBD> tous les objets (joueurs, murs, boules)
* permet de m<EFBFBD>moriser la position de l'objet et de g<EFBFBD>rer les collisions
*
*/
public abstract class Objet {
/**
* position X de l'objet
*/
protected Integer posX ;
/**
* position Y de l'objet
*/
protected Integer posY ;
/**
* contr<EFBFBD>le si l'objet actuel touche l'objet pass<EFBFBD> en param<EFBFBD>tre
* @param objet contient l'objet <EFBFBD> contr<EFBFBD>ler
* @return true si les 2 objets se touchent
*/
public Boolean toucheObjet (Objet objet) {
return null;
}
}

View file

@ -0,0 +1,16 @@
package outils.connexion;
/**
* Permet la récupération asynchrone d'une réponse
* @author emds
*
*/
public interface AsyncResponse {
/**
* Méthode à redéfinir pour récupérer la réponse de l'ordinateur distant
* @param connection contient l'objet qui permet de recontacter l'ordinateur distant (pour un envoi)
* @param ordre contient "connexion" si nouvelle connexion, "reception" si nvelle information reçue, "deconnexion" si déconnexion
* @param info contient l'information reçue (si ordre = "réception")
*/
void reception(Connection connection, String ordre, Object info);
}

View file

@ -0,0 +1,38 @@
package outils.connexion;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JOptionPane;
/**
* Gestion d'un client : création d'une connexion cliente
* @author emds
*
*/
public class ClientSocket {
/**
* Constructeur : crée le socket de type client pour se connecter à un serveur (avec son ip et port d'écoute)
* @param delegate instance de la classe vers laquelle il faut transférer les réponses
* @param ip adresse IP du serveur
* @param port numéro port d'écoute du serveur
*/
public ClientSocket (AsyncResponse delegate, String ip, int port) {
try {
Socket socket = new Socket(ip, port);
System.out.println("connexion serveur réussie");
// la connexion ne peut se faire que si un objet delegate existe (pour récupérer la réponse)
if(delegate != null) {
// création d'une connexion pour ce client, pour la communication avec le serveur (envoi et réception d'informations)
new Connection(socket, delegate) ;
}
} catch (UnknownHostException e) {
JOptionPane.showMessageDialog(null, "serveur non disponible");
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "IP incorrecte");
}
}
}

View file

@ -0,0 +1,109 @@
package outils.connexion;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
/**
* Gestion de la connexion entre 2 ordinateurs distants
* @author emds
*
*/
public class Connection extends Thread {
/**
* canal d'entrée
*/
private ObjectInputStream in ;
/**
* canal de sortie
*/
private ObjectOutputStream out ;
/**
* objet de lien avec une autre classe qui implémente AsyncResponse pour transférer les réponses
*/
private AsyncResponse delegate;
/**
* Constructeur : crée une connexion à partir d'un socket (contenant les spécificités de l'ordinateur distant)
* @param socket objet de connexion de type serveur ou client
* @param delegate instance de la classe vers laquelle il faut transférer les réponses
*/
public Connection(Socket socket, AsyncResponse delegate) {
this.delegate = delegate;
// création du canal de sortie pour envoyer des informations
try {
this.out = new ObjectOutputStream(socket.getOutputStream()) ;
} catch (IOException e) {
System.out.println("erreur création canal out : "+e);
System.exit(0);
}
// création du canal d'entrée pour recevoir des informations
try {
this.in = new ObjectInputStream(socket.getInputStream()) ;
} catch (IOException e) {
System.out.println("erreur création canal in : "+e);
System.exit(0);
}
// démarrage du thread d'écoute (attente d'un message de l'ordi distant)
this.start() ;
// envoi de l'instance de connexion vers la classe qui implémente AsyncResponse pour récupérer la réponse
this.delegate.reception(this, "connexion", null);
}
/**
* Envoi d'un objet vers l'ordinateur distant, sur le canal de sortie
* @param unObjet contieny l'objet à envoyer
*/
public synchronized void envoi(Object unObjet) {
// l'envoi ne peut se faire que si un objet delegate existe (pour récupérer la réponse)
if(delegate != null) {
try {
this.out.reset();
out.writeObject(unObjet);
out.flush();
} catch (IOException e) {
System.out.println("erreur d'envoi sur le canal out : "+e);
}
}
}
/**
* Méthode thread qui permet d'attendre des messages provenant de l'ordi distant
*/
public void run() {
// permet de savoir s'il faut continuer à écouter
boolean inOk = true ;
// objet qui va récupérer l'information reçue
Object reception ;
// boucle tant qu'il faut écouter
while (inOk) {
try {
// réception d'un objet sur le canal d'entrée
reception = in.readObject();
// envoi de l'information reçue vers la classe qui implémente AsyncResponse pour récupérer la réponse
delegate.reception(this, "reception", reception);
} catch (ClassNotFoundException e) {
// problème grave qui ne devrait pas se produire : arrêt du programme
System.out.println("erreur de classe sur réception : "+e);
System.exit(0);
} catch (IOException e) {
// envoi de l'information de déconnexion vers la classe qui implémente AsyncResponse pour récupérer la réponse
delegate.reception(this, "deconnexion", null);
// demande d'arrêter de boucler sur l'attente d'une réponse
inOk = false ;
// l'ordinateur distant n'est plus accessible
System.out.println("l'ordinateur distant est déconnecté");
// fermeture du canal d'entrée
try {
in.close();
} catch (IOException e1) {
System.out.println("la fermeture du canal d'entrée a échoué : "+e);
}
}
}
}
}

View file

@ -0,0 +1,67 @@
package outils.connexion;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Gestion d'un serveur : création d'une connexion de type serveur pour attendre les connexions de clients
* @author emds
*
*/
public class ServeurSocket extends Thread {
/**
* objet pour une connexion de type serveur (pour attendre des connexions de clients)
*/
private ServerSocket serverSocket ;
/**
* objet de lien avec une autre classe qui implémente AsyncResponse pour transférer les réponses
*/
private AsyncResponse delegate=null;
/**
* Constructeur
* @param delegate instance de la classe vers laquelle il faut transférer les réponses
* @param port numéro port d'écoute du serveur
*/
public ServeurSocket(AsyncResponse delegate, int port) {
// création du socket serveur d'écoute des clients
try {
this.delegate = delegate;
this.serverSocket = new ServerSocket(port);
// le démarrage de l'écoute ne peut se faire que si un objet delegate existe (pour récupérer la réponse)
if(delegate != null) {
this.start();
}
} catch (IOException e) {
// probl<EFBFBD>me grave qui ne devrait pas se produire : arr<EFBFBD>t du programme
System.out.println("erreur grave cr<63>ation socket serveur : "+e);
System.exit(0);
}
}
/**
* M<EFBFBD>thode thread qui va attendre la connexion d'un client
*/
public void run() {
// objet qui va r<EFBFBD>cup<EFBFBD>rer le socket du client qui s'est connect<EFBFBD>
Socket socket ;
// boucle infinie pour attendre un nouveau client
while (true) {
try {
// attente d'une connexion
System.out.println("le serveur attend");
socket = serverSocket.accept();
System.out.println("un client s'est connect<63>");
// cr<EFBFBD>ation d'une connexion vers ce client, pour la communication (envoi et r<EFBFBD>ception d'informations)
new Connection(socket, delegate);
} catch (IOException e) {
// probl<EFBFBD>me grave qui ne devrait pas se produire : arr<EFBFBD>t du programme
System.out.println("erreur sur l'objet serverSocket : "+e);
System.exit(0);
}
}
}
}

121
src/outils/son/Duree.java Normal file
View file

@ -0,0 +1,121 @@
package outils.son;
import java.io.Serializable;
/**
* Représente une durée
*/
public class Duree implements Serializable
{
private long microsecondes;
private int heure, minute, seconde, microseconde;
public Duree()
{
}
public Duree(long microsecondes)
{
this.microsecondes = microsecondes;
long temps = this.microsecondes;
this.microseconde = (int)(temps % 1000000L);
temps = temps / 1000000L;
this.seconde = (int)(temps % 60L);
temps = temps / 60L;
this.minute = (int)(temps % 60L);
temps = temps / 60L;
this.heure = (int)temps;
}
public Duree(int microseconde)
{
if(microseconde < 0)
{
throw new IllegalArgumentException(
"Le nombre de microsecondes ne peut pas être négative");
}
if(microseconde > 999999)
{
throw new IllegalArgumentException("Le nombre de microsecondes ne peut pas être plus de 999999, sinon on a des secondes");
}
this.microseconde = microseconde;
this.microsecondes = (long)this.microseconde;
}
public Duree(int seconde, int microseconde)
{
this(microseconde);
if(seconde < 0)
{
throw new IllegalArgumentException(
"Le nombre de secondes ne peut pas être négative");
}
if(seconde > 59)
{
throw new IllegalArgumentException(
"Le nombre de secondes ne peut pas être plus de 59, sinon on a des minutes");
}
this.seconde = seconde;
this.microsecondes += 1000000L * (long)this.seconde;
}
public Duree(int minute, int seconde, int microseconde)
{
this(seconde, microseconde);
if(minute < 0)
{
throw new IllegalArgumentException(
"Le nombre de minutes ne peut pas être négative");
}
if(minute > 59)
{
throw new IllegalArgumentException(
"Le nombre minutes ne peut pas être plus de 59, sinon on a des heures");
}
this.minute = minute;
this.microsecondes += 60L * 1000000L * (long)this.minute;
}
public Duree(int heure, int minute, int seconde, int microseconde)
{
this(minute, seconde, microseconde);
if(heure < 0)
{
throw new IllegalArgumentException(
"Le nombre d'heure ne peut pas être négative");
}
this.heure = heure;
this.microsecondes += 60L * 60L * 1000000L * (long)this.heure;
}
public Duree(Duree duree)
{
this.microsecondes = duree.microsecondes;
this.microseconde = duree.microseconde;
this.seconde = duree.seconde;
this.minute = duree.minute;
this.heure = duree.heure;
}
public long enMicrosecondes()
{
return this.microsecondes;
}
public long enMillisecondes()
{
return this.microsecondes / 1000L;
}
public int getMicroseconde()
{
return this.microseconde;
}
public int getMilliseconde()
{
return this.microseconde / 1000;
}
public int getSeconde()
{
return this.seconde;
}
public int getMinute()
{
return this.minute;
}
public int getHeure()
{
return this.heure;
}
}

55
src/outils/son/Son.java Normal file
View file

@ -0,0 +1,55 @@
package outils.son;
import java.io.File;
import outils.son.exceptions.*;
import java.io.Serializable;
import java.net.URL;
/**
* Gestion des sons
*
* @author non attribuable
* @version 1.0
*/
public class Son implements Serializable {
/**
* son qui peut être joué
*/
private Sound sound ;
/**
* Création d'un objet de type Sound, à partir d'un fichier de son
* @param nomfic url du fichier
*/
public Son (URL nomfic) {
try {
// this.sound = new Sound(new File(nomfic));
this.sound = new Sound(nomfic);
} catch (SonException ex) {
}
}
/**
* Joue le son une fois
*/
public void play() {
this.sound.boucle(1) ;
}
/**
* ferme le son (libère l'objet de la mémoire)
*/
public void close() {
this.sound.fermer();
}
/**
* Joue le son en boucle (musique de fond)
*/
public void playContinue () {
sound.boucle() ;
}
}

503
src/outils/son/Sound.java Normal file
View file

@ -0,0 +1,503 @@
package outils.son;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Vector;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.Serializable;
import outils.son.ecouteurs.EcouteurSon;
import outils.son.exceptions.SonErreurDiverse;
import outils.son.exceptions.SonErreurLecture;
import outils.son.exceptions.SonException;
import outils.son.exceptions.SonIntrouvableException;
import outils.son.exceptions.SonTypeException;
/**
* Représente un son. <br>
* Les sons les mieux suppoter par Java sont MIDI, AU et certains WAV. <br>
* Pour savoir si un son est accèpté, le seul moyen est d'essayer. <br>
* Si le son ne sera plus utilisé, il faut le détruire par la méthode fermer, <br>
* afin de libérer la mémoire et le flux se trouve le son. <br>
* Attention, une fois détruit, le son n'est plus utilisable. <br>
*/
public class Sound
implements Serializable, Runnable
{
//Durée du son
private Duree duree;
//Flux de kecture audio
private AudioInputStream lecteurAudio;
//Format du fichier audio
private AudioFileFormat formatFichier;
//Format du son
private AudioFormat format;
//Clip jouant le son
private Clip clip;
//Thread permettant de jouer le son en tâche de fond
private Thread thread;
//Nombre de boucle restante à effectué
private int tour;
//pause : inqique si le son est en pause ou non
//fermerALaFin : indique si le son doit être détruit une fois la derniére boucle de son exécutée
private boolean pause, fermerALaFin;
//Ecouteurs des événement sons
private Vector ecouteurs = new Vector();
/**
* Construit un son situé à une URL précise
* @param url URL du son
* @throws SonException Si il y a un probléme de construction du son
*/
public Sound(URL url)
throws SonException
{
this.initialise(url);
}
/**
* Construit un son à partir d'un fichier
* @param fichier Fichier contenant le son
* @throws SonException Si il y a un problème de construction du son
*/
public Sound(File fichier)
throws SonException
{
if(!fichier.exists())
{
throw new SonIntrouvableException(fichier);
}
this.initialise(fichier);
}
//Initialise le son
private void initialise(File fichier)
throws SonException
{
try
{
//Crée le flux
this.lecteurAudio = AudioSystem.getAudioInputStream(fichier);
//Récupére le format du fichier son
this.formatFichier = AudioSystem.getAudioFileFormat(fichier);
//Récupére le format de codage du son
this.format = lecteurAudio.getFormat();
//On ne peut pas ouvrir directement des format ALAW/ULA, il faut les convertir en PCM
if((this.format.getEncoding() == AudioFormat.Encoding.ULAW) ||
(this.format.getEncoding() == AudioFormat.Encoding.ALAW))
{
//convertion du format
AudioFormat tmp = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
this.format.getSampleRate(),
this.format.getSampleSizeInBits() * 2,
this.format.getChannels(),
this.format.getFrameSize() * 2,
this.format.getFrameRate(),
true);
//convertion du flux
this.lecteurAudio = AudioSystem.getAudioInputStream(tmp,
this.lecteurAudio);
//On a convertit le format, si bien qu'il change
this.format = tmp;
}
//On crée une information avec le format du flux et en caculant la logueneur totale du son
DataLine.Info info = new DataLine.Info(
Clip.class,
this.lecteurAudio.getFormat(),
((int)this.lecteurAudio.getFrameLength() *
this.format.getFrameSize()));
//Grac à cette information, on peut creer un clip
this.clip = (Clip)AudioSystem.getLine(info);
//On ouvre le son
reouvrir();
}
catch(UnsupportedAudioFileException uafe)
{
throw new SonTypeException();
}
catch(IOException ioe)
{
throw new SonErreurLecture();
}
catch(Exception e)
{
throw new SonErreurDiverse(e);
}
//On calcul la durée du son en microseconde
this.duree = new Duree(this.longueurSonMicroseconde());
}
private void initialise(URL url)
throws SonException
{
try
{
//Crée le flux
this.lecteurAudio = AudioSystem.getAudioInputStream(url);
//Récupére le format du fichier son
this.formatFichier = AudioSystem.getAudioFileFormat(url);
//Récupére le format de codage du son
this.format = lecteurAudio.getFormat();
//On ne peut pas ouvrir directement des format ALAW/ULA, il faut les convertir en PCM
if((this.format.getEncoding() == AudioFormat.Encoding.ULAW) ||
(this.format.getEncoding() == AudioFormat.Encoding.ALAW))
{
//convertion du format
AudioFormat tmp = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
this.format.getSampleRate(),
this.format.getSampleSizeInBits() * 2,
this.format.getChannels(),
this.format.getFrameSize() * 2,
this.format.getFrameRate(),
true);
//convertion du flux
this.lecteurAudio = AudioSystem.getAudioInputStream(tmp,
this.lecteurAudio);
//On a convertit le format, si bien qu'il change
this.format = tmp;
}
//On crée une information avec le format du flux et en caculant la logueneur totale du son
DataLine.Info info = new DataLine.Info(
Clip.class,
this.lecteurAudio.getFormat(),
((int)this.lecteurAudio.getFrameLength() *
this.format.getFrameSize()));
//Grac à cette information, on peut creer un clip
this.clip = (Clip)AudioSystem.getLine(info);
//On ouvre le son
reouvrir();
}
catch(UnsupportedAudioFileException uafe)
{
throw new SonTypeException();
}
catch(IOException ioe)
{
throw new SonErreurLecture();
}
catch(Exception e)
{
throw new SonErreurDiverse(e);
}
//On calcul la durée du son en microseconde
this.duree = new Duree(this.longueurSonMicroseconde());
}
/**
* Joue le son une fois
*/
public void jouer()
{
//Si le son n'est pas initialiser, on l'initialise
if(this.thread == null)
{
this.thread = new Thread(this);
this.thread.start();
}
//On va le jouer une fois
this.tour = 1;
}
/**
* Joue le son plusieurs fois
* @param nbFois Nombre de fois que le son est joué
*/
public void boucle(int nbFois)
{
//Si le son n'est pas initialiser, on l'initialise
if(this.thread == null)
{
this.thread = new Thread(this);
this.thread.start();
}
//On va le jouer nbFois fois
this.tour = nbFois;
}
/**
* Joue le son un tn trés grand nombre de fois
*/
public void boucle()
{
this.boucle(Integer.MAX_VALUE);
}
/**
* Action du son, ne jamais appelé cette méthode directement, elle est public pour respecter l'implémentation de Runnable
*/
public void run()
{
//Tant que le son est vivant
while(this.thread != null)
{
//Pause de 0.123 seconde
try
{
this.thread.sleep(123);
}
catch(Exception e)
{}
//Si on doit jouer le son au moins une fois
if(this.tour > 0)
{
//On lance le son
this.clip.start();
//pause de 0.099 seconde (le son est jouer pendant ce temps)
try
{
this.thread.sleep(99);
}
catch(Exception e)
{}
//Tant que le son n'est pas terminer ou que l'on soit en pause et est vivant
while((this.clip.isActive() || this.pause) && (this.thread != null))
{
//Si on est pas en pause, on avance sur le son
if(!this.pause)
{
this.avancer();
}
//Pause de 0.099 seconde
try
{
this.thread.sleep(99);
}
catch(Exception e)
{
break;
}
}
//Arréte le son
this.clip.stop();
//On se place au début du son
this.placeMicroseconde(0);
//On à un tour de moins à jouer
this.tour--;
if(this.tour < 1)
{
//Si on a fini de jouer, on tremine
this.terminer();
//Si on doit fermer à la fin, on ferme définitivement le son
if(this.fermerALaFin)
{
this.fermer();
}
}
}
}
}
//Permet de réouvrir le son, ou de l'ouvrir
private void reouvrir()
throws Exception
{
this.clip.open(this.lecteurAudio);
}
/**
* Met le son en pause
*/
public void pause()
{
//Si on est pas déjà en pause, on se met en pause
if(!this.pause)
{
this.clip.stop();
this.pause = true;
}
}
/**
* Reprend le son ou il était rendu (enlève la pause)
*/
public void reprise()
{
//Si on est en pause, on enléve la pause
if(this.pause)
{
pause = false;
this.clip.start();
}
}
/**
* Arrête de jouer le son et retour du son au début
*/
public void stop()
{
this.clip.stop();
this.placeMicroseconde(0);
this.pause = false;
this.tour = 0;
this.thread = null;
}
/**
* Détruit proprement le son
*/
public void fermer()
{
this.stop();
this.clip.close();
this.clip = null;
this.duree = null;
this.ecouteurs.clear();
this.ecouteurs = null;
this.format = null;
this.formatFichier = null;
}
/**
* Indique si le son sera détruit aprés sa derniére fois ou il joue
* @return <b>true</b> si le son est détruit quand c'est finit
*/
public boolean estFermerALaFin()
{
return fermerALaFin;
}
/**
* Change l'état de fermeture à la fin
* @param fermer <b>true</b> pour indiqué que l'on désire que le son soit détruit aprés la derniére fois qu'il joue
*/
public void setFermerALaFin(boolean fermer)
{
this.fermerALaFin = fermer;
}
/**
* Longeur du son en microseconde
* @return Longueur du son
*/
public long longueurSonMicroseconde()
{
return this.clip.getMicrosecondLength();
}
/**
* Nombre de microsecondes écoulées depuis le début du son
* @return Durée en microseconde de l'écoute
*/
public long getRenduMicroseconde()
{
return this.clip.getMicrosecondPosition();
}
/**
* Durée de l'écoute
* @return Durée de l'écoute
*/
public Duree getRendu()
{
return new Duree(this.getRenduMicroseconde());
}
/**
* Place le son à cette durée en milliseconde.
* @param microseconde Place à laquelle on désire commencé le son
*/
public void placeMicroseconde(long microseconde)
{
this.clip.setMicrosecondPosition(microseconde);
}
/**
* Place le son à cette durée
* @param duree Place à laquelle on désire commencé le son
*/
public void placeDuree(Duree duree)
{
this.placeMicroseconde(duree.getMicroseconde());
}
/**
* Remet le son au départ
*/
public void placeDepart()
{
this.clip.setMicrosecondPosition(0);
}
/**
* Indique si le son est en pause
* @return <b> true</b> si le son est en pause
*/
public boolean estEnPause()
{
return this.pause;
}
/**
* Indique si le son est entrain d'être jouer
* @return <b>true</b> si le son est entrain d'être joué
*/
public boolean estEntrainDeJouer()
{
return!this.pause && (this.tour > 0);
}
/**
* Ajout un écouteur d'événement son
* @param ecouteur Ecouteur ajouté
*/
public void ajouteEcouteurSon(EcouteurSon ecouteur)
{
if(ecouteur != null)
{
this.ecouteurs.addElement(ecouteur);
}
}
/**
* Retire un écouteur d'événement son
* @param ecouteur Ecouteur retiré
*/
public void retireEcouteurSon(EcouteurSon ecouteur)
{
if(ecouteur != null)
{
this.ecouteurs.removeElement(ecouteur);
}
}
//Indique à tout les écouteurs d'événements son, que le son est terminé
private void terminer()
{
Thread t = new Thread()
{
public void run()
{
Sound.this.terminer1();
}
};
t.start();
}
//Indique à tout les écouteurs d'événements son, que le son est terminé
private void terminer1()
{
int nb = this.ecouteurs.size();
for(int i = 0; i < nb; i++)
{
EcouteurSon ecouteur = (EcouteurSon)this.ecouteurs.elementAt(i);
ecouteur.sonTermine(this);
}
}
//Indique à tout les écouteurs d'événements son, que le son a avancé
private void avancer()
{
Thread t = new Thread()
{
public void run()
{
Sound.this.avancer1();
}
};
t.start();
}
//Indique à tout les écouteurs d'événements son, que le son a avancé
private void avancer1()
{
int nb = this.ecouteurs.size();
for(int i = 0; i < nb; i++)
{
EcouteurSon ecouteur = (EcouteurSon)this.ecouteurs.elementAt(i);
ecouteur.sonChangePosition(this);
}
}
/**
* Renvoie la durée du son
* @return La durée du son
*/
public Duree getDuree()
{
return this.duree;
}
}

View file

@ -0,0 +1,21 @@
package outils.son.ecouteurs;
import outils.son.Sound;
/**
* Indique que l'objet écoute les événements sons <br>
*/
public interface EcouteurSon
{
/**
* Indique qu'un son est terminé
* @param son Son qui a finit de joué
*/
public void sonTermine(Sound son);
/**
* Indique qu'un son vient d'avancer sur sa lecture
* @param son Son qui est entrain d'avancer
*/
public void sonChangePosition(Sound son);
}

View file

@ -0,0 +1,21 @@
package outils.son.exceptions;
import java.io.Serializable;
/**
* Exception levée pour signale un manque de droit, un flux coupé en cours de routez, une erreur ... <br>
*/
public class SonErreurDiverse
extends SonException implements Serializable
{
/**
* Construit l'exception
* @param e Exception générée à la construction du son
*/
public SonErreurDiverse(Exception e)
{
super("Une erreur s'est produite lors de l'analyse du son : " +
e.getMessage());
}
}

View file

@ -0,0 +1,20 @@
package outils.son.exceptions;
import java.io.Serializable;
/**
* Exception levée pour signaler une erreur de lecture du son <br>
*/
public class SonErreurLecture
extends SonException implements Serializable
{
/**
* Construit l'exception
*/
public SonErreurLecture()
{
super("Erreur lors de la lecture du son");
}
}

View file

@ -0,0 +1,20 @@
package outils.son.exceptions;
import java.io.Serializable;
/**
* Excpetion générale <br>
*/
public class SonException
extends Exception implements Serializable
{
/**
* Construit l'exception
* @param message Message de l'exception
*/
public SonException(String message)
{
super(message);
}
}

View file

@ -0,0 +1,38 @@
package outils.son.exceptions;
import java.io.File;
import java.net.URL;
import java.io.Serializable;
/**
* Exception levée pour indiquer que le son n'a pas été trouvé <br>
*/
public class SonIntrouvableException
extends SonException implements Serializable
{
/**
* Constrtuit l'exception pour les fichiers
* @param fichier Fichier non trouvé
*/
public SonIntrouvableException(File fichier)
{
super("Le fichier " + fichier.getAbsolutePath() + " est introuvable");
}
/**
* Construit l'exception pour les URL
* @param url URL non trouvée
*/
public SonIntrouvableException(URL url)
{
super("L'URL : " + url.getFile() + " est introuvable");
}
/**
* Construit l'exception pour les sons de la ressource
* @param nom Nom de la ressource non trouvée
*/
public SonIntrouvableException(String nom)
{
super("Le son : " + nom + " est introuvable");
}
}

View file

@ -0,0 +1,20 @@
package outils.son.exceptions;
import java.io.Serializable;
/**
* Exception levée si le type de son n'est pas reconnu <br>
*/
public class SonTypeException
extends SonException implements Serializable
{
/**
* Construit l'exception
*/
public SonTypeException()
{
super("Le type du son n'est pas reconnu");
}
}