Exposé Flash 3 - Tir aux canards - BRIGOLLE Mathieu GI04Printemps 07.

Post on 03-Apr-2015

103 views 0 download

Transcript of Exposé Flash 3 - Tir aux canards - BRIGOLLE Mathieu GI04Printemps 07.

Exposé Flash 3 - Tir aux canards -

BRIGOLLE Mathieu GI04 Printemps 07

Exposé Flash 3

Objectif :

Réalisation d’un jeu de tir aux canards

http://wwwetu.utc.fr/~mbrigoll/TirOCanard.swf

Quelques mots sur la POO1.

- Qu’est-ce que la POO ?

Technique de programmation

Chaque tâche de l’application est réalisée par un objet spécialisé dans sa réalisation

- Classes et Objets : ne pas confondre ces deux notions

var _sonCanard:Sound = new Sound();var _sonTir:Sound = new Sound();

Ici, « Sound » désigne la Classe, « _sonCanard » et « _sonTir » désignent deux Objets de type « Sound ».

- Notion d’héritage

Une classe peut hériter/dériver d’une autre classe.

http://wwwetu.utc.fr/~mbrigoll/Objet.zip

Jeu de Tir aux Canards2.

http://wwwetu.utc.fr/~mbrigoll/Flash3_files.zip

Créer un document fla, paramétrage du document :Dimensions : 800 x 600 pixelsArrière-plan : noir30 images par seconde

Créer deux calques : l’un pour le code, l’autre pour l’interface.

Chaque calque doit contenir 3 images clefs vides :Sur l’un des calques, les nommer « Menu », « Jeu » et « Fin »

Dans la bibliothèque, créer trois répertoires avec les mêmes noms que les images.

Création du menu2.1.

txtPseudo

rdFacilerdNormalrdCauchemar

btnPlay

Sur le calque Interface, Image 1 :

Code à placer dans le calque Code de l’image 1 :

stop();

// Initialiser le contenu du champs de saisi contenant le pseudotxtPseudo.text = "";// Changer la couleur de fond du champ de textetxtPseudo.backgroundColor = "0xC9C072";txtPseudo.background = true; // Activer la couleur de fond

rdFacile.fontName = "Garamond";rdFacile.fontSize = 22;

rdNormal.fontName = "Garamond";rdNormal.fontSize = 22;

rdCauchemar.fontName = "Garamond";rdCauchemar.fontSize = 22;

Création du menu2.1.

Suite du code à placer dans le calque Code de l’image 1 :

btnPlay.onRelease = function() // quand on relâche le bouton{

if(txtPseudo.text != "") // Si le pseudo a été saisi{

// on mémorise la difficulté qui va servir dans l'image suivanteif(rdFacile.selected)

_global.difficulte = "facile";else if(rdNormal.selected)

_global.difficulte = "normal";else if(rdCauchemar.selected)

_global.difficulte = "cauchemar";

// on mémorise le pseudo_global.pseudo = txtPseudo.text;

// Aller à l'image 2 et s'arrêter là gotoAndStop("Jeu");

}}

Création du menu2.1.

Création de la partie jeu2.2.

Sur le calque Interface, Image 2 : importer le fond (fond_shoot.png)

Création du clip « fusil » :

- Insérer l’image « canon » en -52 ; -170

- Placer une occurrence nommée « fusil » du clip créé sur le calque Interface de l’image 2

- La placer en : 350 ; 430

Création du clip « souris » :

- Exporte le clip pour ActionScript car il sera uniquement utilisé par l’intermédiaire d’ActionScript

- Insérer l’image « cible » en -35 ; -35

Création des clips2.2.1.

Création du clip « canard » :

- Exporter pour ActionScript

- Insérer l’image « duck1 »Lorsque Flash vous propose d’importer toute la séquence, répondez oui, il importera les images « duck2 » et « duck3 » dans les images 2 et 3

- Placer les trois images en : -110 ; -100Ce placement définit le centre de rotation de l’image pour plus tard.

- Déplacer l’image 3 en image 10 et l’image 2 en image 5

- Insérer une image clef non vide en image 9

- Placer le code suivant dans l’image 9 :gotoAndPlay(1);

Création des clips2.2.1.

Code à placer dans un nouveau fichier nommé « souris.as » :

// Classe qui sera liée au clip sourisclass souris extends MovieClip{

// Quand ce clip sera chargé sur la scènefunction onLoad(){// Méthode permettant d'automatiquement suivre la souris

this.startDrag(true);// On cache l'image de la souris (la flèche blanche)

Mouse.hide();}

// Quand ce clip sera détruitfunction onUnload(){

this.stopDrag(); // On arrête de suivre la sourisMouse.show(); // On réaffiche la souris

}}

Création de la classe “souris”2.2.2.

Code à placer dans un nouveau fichier nommé « daffy.as » :

// Classe daffy dérivant de la classe MovieClipclass daffy extends MovieClip{

// Constructeurfunction daffy(){

// Code qui sera remplacé plus tard _x = _y = 150;

}

// Fonction appelée à chaque rafraichissement d'imagefunction onEnterFrame(){}

/* Action quand on clique sur le canard */function onPress(){

// Change l'image du canard this.gotoAndStop(10);

}}

Création de la classe “daffy” – Partie 12.2.3.

Code à placer dans un nouveau fichier nommé « jeu.as » :

// Importation des classes daffy et souris utiliséesimport daffy;import souris;

class jeu{

// Profondeur courante pour la création de clip sur la scèneprivate var _profondeurCourante:Number = 1;// Interval de temps entre l'apparition des canardsprivate var _tempsCanard:Number = 700;

// Tableau qui va contenir les références aux callbacks : // [0] interval entre l'apparition de chaque canard// [1] timer pour le chrono du jeuprivate var _interval:Array = new Array( 2 );

// Référence le clip de la sourisprivate var _souris:souris = null;

Création de la classe “jeu” – Partie 12.2.4.

// Constructeur de la classe :function jeu(){

// Cré les derniers éléments d'interfacesetInterface();

// Définition des timers_interval[0] = setInterval(this, "nouveau_canard",

_tempsCanard);}

private function setInterface(){

// Création d'une instance du clip souris// Le clip est créé à la profondeur 1048574 car :// - On veut être sûr qu’il soit au-dessus des canards// - 1048575 est le dernier index pouvant être supprimé mais// il est réservée par les composants AS2// Voir l'aide de removeMovieClip_root.attachMovie("souris", "souris", 1048574);// On garde la référence de la souris pour la détruire à la fin_souris = _root.souris;

}

Création de la classe “jeu” – Partie 12.2.4.

// Fonction permettant de créer un nouveau canard sur// la scèneprivate function nouveau_canard() {

_root.attachMovie("canard","mon_canard" +_profondeurCourante, _profondeurCourante);

_profondeurCourante++;

// Le temps du test, on détruit le timer pour ne// créer qu’un seul canard…clearInterval(_interval[0]);

}}

Création de la classe “jeu” – Partie 12.2.4.

Premier test du travail réalisé

Insérer le code suivant dans le calque Code de l’image 2 :

// Importer le fichier jeu.asimport jeu;

/* Liaison de notre classe souris avec l'objet souris de la bibliothèque */Object.registerClass("souris",souris);

/* Liaison de notre classe daffy avec l'objet canard de la bibliothèque */Object.registerClass("canard",daffy);

/* On instancie un objet jeu */var monJeu:jeu = new jeu();

En testant, vous devriez avoir un canard qui bat des ailes, la cible qui suit votre souris sans que le curseur soit visible. Si vous cliquez sur le canard, celui-ci sera tué.

Nous allons maintenant animer le canard.

// Classe daffy dérivant de la classe MovieClipclass daffy extends MovieClip{

// Déclaration et initialisation des variables// Indique si le canard est mort ou non private var mort:Boolean = false;// Indique si le canard est tombé par terre private var crash:Boolean = false;private var vitesse:Number = 0; // Vitesse du canard// Dans quel sens va le canard :// (1 de gauche à droite, et -1 de droite à gauche)private var sens:Number = 1;

// Déclaration et initialisation de la variable statique total// Permet de compter combien de canard sont utilisésprivate static var total:Number = 0;public static function get Total(){ return total; }public static function set Total(newTotal:Number){ total = newTotal; }

Création de la classe “daffy” – Partie 22.2.5.

// Constructeurfunction daffy(){

// La vitesse est pseudo-aléatoire : entre 3 et 8 vitesse = Math.random() * 5 + 3;// sens également pseudo-aléatoire (ici sens = 0 ou 1) sens = Math.round(Math.random());if(sens == 0) sens = -1; // sens = -1 ou 1 uniquement

// Donne une grosseur pseudo-aléatoire aux canards _xscale = _yscale = Math.random() * 40 + 20;// le canard est dirigé vers le sens ou il va _xscale = _xscale * -sens;

// donne une position pseudo-aléatoire aux canards

_y = Math.random() * 150 + 40;if(sens == 1)

// s’il va de gauche à droite, il arrive par la gauche_x = -_width;

else // sinon par la droite_x = 800;

// Un canard de plus vient d'être créétotal++;

}

Création de la classe “daffy” – Partie 22.2.5.

// Fonction appelée à chaque rafraichissement d'imagefunction onEnterFrame(){

if(not crash) // Si le canard n'est pas au sol{

// Déplace le canard horizontalement _x += vitesse * sens;// Si le canard est sortit de l'écran :if(((_x - _width > 800) or (_x + _width < 0))

and not mort){

sens = -sens; // On change son sens// On inverse horizontalement l'image_xscale = -_xscale;

}if(mort) // S'il a été touché, il faut qu'il tombe{

// Fait descendre le canard _y = _y + 1 + (_rotation*sens) / 4; // Fait tourner l'image du canard if(_rotation < 30) _rotation += sens; // S'il touche terre : il est crashé if(_y > 450) crash = true;

}}

Création de la classe “daffy” – Partie 22.2.5.

else // Le canard est par terre {

_alpha--; // On réduit sa transparenceif(_alpha < 0) // S'il n'est plus visible {

// On le retire du total des canard affichés total--;// On le retire de la scène this.removeMovieClip();

}}

}

/* Action quand on clique sur le canard */function onPress(){

// Si le canard n'est pas déjà mortif(!mort){

mort = true; // Change l'état du canardthis.gotoAndStop(10); // Change l'image du canard

}}} // Fin de la classe daffy

Création de la classe “daffy” – Partie 22.2.5.

Création de la classe “jeu” – Partie 22.2.5.

Ajoutez le code suivant à la classe jeu :

1 – Dans la partie de déclaration des variables :

// Nombre de canard maximal en même temps durant le jeuprivate var _nbCanardMax:Number = 10;

2 – A la place de la fonction nouveau_canard :

// Fonction permettant de créer un nouveau canard sur la scèneprivate function nouveau_canard() {

if(daffy.Total < _nbCanardMax) {

_root.attachMovie("canard","mon_canard" + _profondeurCourante,_profondeurCourante);

_profondeurCourante++;}

}

3 – Tester le résultat

Création de la classe “jeu” – Partie 22.2.6.

Nous allons maintenant animer le canon et mettre un peu d’ambiance. Commencez par ajouter le code suivant à la classe jeu :

1 – Dans la partie de déclaration des variables :

// Son joué lors de l'apparition d'un canardprivate var _sonCanard:Sound = null;// Musique jouée pendant une partieprivate var _sonMusique:Sound = null;// Son joué lors d'un tirprivate var _sonTir:Sound = null;

2 – Dans le constructeur de la classe :

// Charge les sonssetSounds();

// Indique aux objets Key et Mouse (gérés par Flash) que// cette classe est à l'écoute des évènements provenants// respectivements du clavier et de la sourisKey.addListener(this);Mouse.addListener(this);

Création de la classe “jeu” – Partie 22.2.6.

3 – Les procédures suivantes :

// Chargements des trois sons du jeuprivate function setSounds(){

_sonCanard = new Sound();_sonCanard.loadSound("sons/duck.mp3");_sonCanard.setVolume(80);

_sonMusique = new Sound();_sonMusique.onLoad = function()

  {  // Dès que zikette est chargée, on commence

// à le jouerthis.start();

};_sonMusique.loadSound("sons/zikette.mp3");_sonMusique.setVolume(80);

_sonTir = new Sound();_sonTir.loadSound("sons/gunfire.mp3");_sonTir.setVolume(100);

}

Création de la classe “jeu” – Partie 22.2.6.// Fonction qui sera déclenchée par l'objet Key lorsque l'utilisateur// appuie sur une touche. Elle ne sera bien sûr déclenchée que si la// commande Key.addListener(this) a déjà été exécutée...private function onKeyDown(){

// On teste si la flèche gauche est enfoncéeif(Key.isDown(Key.LEFT))

_root.fusil._x = _root.fusil._x - 4;else if(Key.isDown(Key.RIGHT))

_root.fusil._x = _root.fusil._x + 4;}    // Fonction qui sera déclenchée par l'objet Mouse lorsque l'utilisateur// bouge la souris. Elle ne sera bien sûr déclenchée que si la commande// Mouse.addListener(this) a déjà été exécutée...private function onMouseMove() {

// calcul d'angle (trigo de 5eme ;)var x = _root.souris._x - _root.fusil._x;var y = _root.souris._y - _root.fusil._y;var angle = -Math.atan(x / y) * 180 / Math.PI;if(angle < -40) angle = -40; // limite l'orientation du fusil

  if(angle > 40) angle = 40;_root.fusil._rotation = angle; // définit l'orientation

}

Création de la classe “jeu” – Partie 22.2.6.// Fonction qui sera déclenchée par l'objet Mouse lorsque// l'utilisateur appuie sur un bouton de la souris. Elle ne sera// bien sûr déclenchée que si la commande Mouse.addListener(this)// a déjà été exécutée...private function onMouseDown(){

_sonTir.start(); // on joue le le son pour le tir du fusil}

4 – Dans la fonction nouveau_canard, complétez l’ancienne ligne commençant par « _root » :

_root.attachMovie("canard", "mon_canard" + _profondeurCourante,profondeurCourante, {son:_sonCanard});

5 – Dans la classe daffy : ligne 1 dans les variables, ligne 2 dans le constructeur

// Son à utiliser lors de l'initialisation du canardprivate var son:Sound = null;

// Si le son a été créé à l'initialisation, on le joueif(son != null) son.start();

Testez votre jeu de tir au canard

Niveaux de jeu et Score2.2.7.Ajoutez le canard mort (duck3), le chrono et les cartouches

Niveaux de jeu et Score2.2.7.Ajoutez les codes suivants dans la classe jeu :

1 – Dans la zone de déclaration des variables

private var _temps:Number = 60; // Chrono du jeu private var _munitions:Number = 60; // Munitions restantes private var _canardTues:Number = 0; // Nombre de canards tués // Référence un champ de texte qui va afficher le nombre de canard tuésprivate var _txtCanardTues:TextField = null;// Référence au champ de texte qui va afficher le temps de jeu restantprivate var _txtChrono:TextField = null;// Référence au champ de texte qui affichera le nombre de munitions restantesprivate var _txtMunitions:TextField = null;

2 – Au niveau du constructeur :

function jeu(maxDuck:Number, time:Number, ammo:Number, tpsCanard:Number){

_nbCanardMax = maxDuck;_temps = time;_tempsCanard = tpsCanard;_munitions = ammo;_interval[1] = setInterval(this, "timer", 1000);

…}

Niveaux de jeu et Score2.2.7.3 – Dans la fonction setInterface() :

/* Création des 3 textFields pour les indicateurs, format des champs de texte */var formatTxt:TextFormat = new TextFormat();formatTxt.bold = true;formatTxt.size = 32;        /* Afficheur pour le nombre de canards tués */_root.createTextField("CanardTues_txt", _profondeurCourante, 70,

507, 102, 63);_txtCanardTues = _root.CanardTues_txt;_txtCanardTues.setNewTextFormat(formatTxt);_txtCanardTues.text = "0";_profondeurCourante++;        /* Afficheur pour le chrono */_root.createTextField("Chrono_txt", _profondeurCourante, 200, 507,

102, 63);_txtChrono = _root.Chrono_txt;_txtChrono.setNewTextFormat(formatTxt);_txtChrono.text = _temps.toString();_profondeurCourante++;

Niveaux de jeu et Score2.2.7./* Afficheur pour les munitions */_root.createTextField("Munitions_txt", _profondeurCourante, 660,

507, 102, 63);_txtMunitions = _root.Munitions_txt;_txtMunitions.setNewTextFormat(formatTxt);_txtMunitions.text = _munitions.toString();_profondeurCourante++;

4 – Dans la fonction nouveau_canard, complétez l’ancienne ligne commençant par « _root » :

_root.attachMovie("canard","mon_canard" + _profondeurCourante,_profondeurCourante, {son:_sonCanard,_jeu:this});

5 – Modifiez la procédure onMouseDown :

private function onMouseDown(){

_sonTir.start(); // on joue le le son pour le tir du fusilmunitions = munitions - 1;_global.score--;if (_munitions == 0) fin();

}

Niveaux de jeu et Score2.2.7.6 – Ajoutez les fonctions suivantes :

// Propriété publique qui retourne ou modifie le nombre de munitions restantespublic function get munitions():Number{ return _munitions; }public function set munitions(n:Number){

_munitions = n;_txtMunitions.text = n.toString();

}    // Propriété publique qui retourne ou modifie le temps restantspublic function get temps(){ return _temps; }public function set temps(n:Number){

_temps = n;_txtChrono.text = n.toString();

}

Niveaux de jeu et Score2.2.7.// Propriété publique qui retourne ou modifie le nombre de canards tuéspublic function get canardTues():Number{ return _canardTues; }public function set canardTues(n:Number){

_canardTues = n;_txtCanardTues.text = n.toString();

}

// Fonction appelée chaque seconde par l'un des timers définient dans la// variable _interval. Elle permet de compter le temps écouléprivate function timer(){

temps = temps - 1;_global.score = _global.score - 0.1;if(_temps == 0) fin();

}

Niveaux de jeu et Score2.2.7.// Fonction appelée à la fin du jeu pour supprimer tous les éléments// qui doivent l'être :// - éléments d'interface créés dynamiquement (sinon ils resteront// sur les images suivantes)// - timers, Listeners…private function fin(){

// On détruit les intervales, puis l’interface.if(_interval[0] != null) clearInterval(_interval[0]);if(_interval[1] != null) clearInterval(_interval[1]);

        _souris.removeMovieClip();_txtCanardTues.removeTextField();_txtChrono.removeTextField();_txtMunitions.removeTextField();

        // On retire les écouteurs sur le clavier et la sourisKey.removeListener(this);Mouse.removeListener(this);

        _sonMusique.stop(); // On arrête la musique

        // On redirige vers l'image 3_root.gotoAndStop("Fin");

}

Niveaux de jeu et Score2.2.7.7 – Gestion du jeu dans la classe daffy :

- Dans les déclarations de variables

// Référence à la partie dans laquelle le canard est utiliséprivate var _jeu:jeu = null;

- Au début de onEnterFrame (ne pas oublier de rajouter un else avant le if qui suit)

if(_jeu.temps == 0 || _jeu.munitions == 0){

// jeu terminé on retire toutes les instances de la scène. this.removeMovieClip();

total--;}

- Dans le if de onPress :

_jeu.canardTues = _jeu.canardTues + 1; // Un canard de plus de tué_global.score = _global.score + 4

Niveaux de jeu et Score2.2.7.8 – Modification de la création de l’objet monJeu dans le code de l’image 2 :

A la place de :

/* On instancie un objet jeu */var monJeu:jeu = new jeu();

Mettre :

_global.score=0;

/* On instancie le jeu et on lance la partie */var monJeu:jeu = null;if(_global.difficulte == "facile")    monJeu = new jeu(10, 60, 80, 700);else if(_global.difficulte == "normal")    monJeu = new jeu(20, 60, 70, 500);else if(_global.difficulte == "cauchemar")    monJeu = new jeu(40, 60, 60, 300);

Création de la partie d’affichage du score2.3.

Sur le calque Interface, Image 3 :

txt_msg : variable msg

txt_score : variable scorefinal

btnMenu

btnTryAgain

Dans le calque Code, ajouter le code suivant :

scorefinal = _global.score;msg = "Bravo " + _global.pseudo + " !";

btnMenu.onRelease = function(){

gotoAndStop("Menu");}

btnTryAgain.onRelease = function(){

gotoAndStop("Jeu");}

Création de la partie d’affichage du score2.3.