Un jeu de logique en Flash

Licence

Ce code est fourni sous une licence CC-By (cf. fin de page).
De plus, il est interdit de recompiler le jeu "tel quel" en supprimant le lien «Plus de jeux», la mention «tel quel» restant à l'appréciation de l'auteur original du code source (copie, plagiat...).

À propos du code

Le code est réparti en classes claires et nettes.
L'ensemble du fichier représente moins de 10ko !

La position de chaque noeud est calculée à la volée, à l'aide d'une méthode récursive plutôt performante.

Classe principale A-Graphe

Fichiers de bases :

Code source : Agraphe.as
  • Langage : actionscript3
  • ΔT : 0.114s
  • Taille :5636 caractères
//Code original par Neamar. Réutilisation libre.
//neamar@neamar.fr

//Ligne de commande pour compiler :
//(après s'être placé dans le bon dossier, cf. http://neamar.fr/Res/Compiler_AS3/)
//
//bash mxmlc Sources/A-graphe/Agraphe.as -default-size 640 480 -compiler.strict

//Life begins when you can spend your spare time programming instead of
//watching television.

package
{
        import flash.display.Sprite;//La classe de base, fort utile !
        import flash.events.*;//Chargons tous les évenements ce sera plus simple :)
        import flash.geom.Point;//Un point tout ce qu'il y a de plus normal : défini par (x,y).
        import flash.text.TextField;//Champ de texte. Classe assez vaste, utilisée uniquement pour l'affichage de texte ici

        import flash.filters.BitmapFilter;//Classe globale pour les filtres
        import flash.filters.GlowFilter;//Filtre d'irridescence (éclairage, le plus utilisé)
        import flash.filters.BlurFilter//Flouter
        import flash.filters.BevelFilter;

        import flash.net.URLRequest;//Prépare une requete.
        import flash.net.sendToURL;//Execute une requete sans récuperer la réponse
    import flash.display.Loader;//Chargement d'un fichier normal, et récupère le contenu
    import flash.system.LoaderContext;//Forcer le chargement du crossdomain.xml
        import flash.net.SharedObject;//Sauvegarde locale



        [SWF(width = "640", height = "480", frameRate = 25)];//Quelques paramètres pour la compilation. Ils sont cependant redéfinis dans la ligne de commande.

        public class Agraphe extends Sprite
        {
                public var Fond:Niveau;//Fond est un Sprite Niveau, qui contient le niveau en cours.

                public const VERSION:String="RC1";//La version
                public var Img_Fond:Loader = new Loader();

                public var SAVE_LOCAL:SharedObject;//L'enregistrement du niveau en cours, et des niveaux unlockés.
                public var SESSION:Object;//Un raccourci vers SharedObject.datas

                public var NumeroNiveauActuel:int=0;
                public var NumeroNiveauUnlockes:int;


                private var GrandPere:Noeud; //GrandPere est présent dans chaque niveau, c'est le noeud final à atteindre.

                function Agraphe():void
                {
//                      Les constantes primitives utilisées tout au long du Flash
                        const FlashWidth:int = 640;
                        const FlashHeight:int = 480;

//                      Récuperer les données locales
                        SAVE_LOCAL = SharedObject.getLocal("AGraphe");
                        SESSION = SAVE_LOCAL.data;

//                      SESSION.NumeroNiveauUnlockes=SESSION.NumeroNiveauActuel=11;
//                      SESSION.NumeroNiveauActuel=SESSION.NumeroNiveauUnlockes=null;

                        if(SESSION.NumeroNiveauActuel==null)
                                SESSION.NumeroNiveauActuel=SESSION.NumeroNiveauUnlockes=NumeroNiveauActuel;//On ne met pas à 0 afin de permettre des tests : lors du débuggage, il suffit de changer une variable pour passer à un niveau.

                        NumeroNiveauUnlockes=SESSION.NumeroNiveauUnlockes;//Recharger les dernières valeurs
                        NumeroNiveauActuel=NumeroNiveauUnlockes;//Commencer au dernier niveau

//                      include "../Trace.as";
                        include "ChangementsNiveaux.as";//Pendant le niveau, test si il est fini. Prépare le passage à un nouveau niveau.
                        include "ChargementNiveaux.as";//La liste des niveaux, les différentes possibilités de le charger (via un String, un Array...)
                        include "Message.as";//La boite de message. Montre un message via la méthode ShowMessage(message:String)
                        include "2Joueurs.as";//Gestion du mod «2 Joueurs»
                        include "Persos.as";//Gestion du mod «Créateur de niveaux»
//              include "Resolution.as";//Non inclus dans la version distribuée. Teste un niveau, renvoie le nombre minimal de noeuds à allumer.

                        SwapBackGround();//Afficher l'image de fond

                        //Enregistrer le nouveau joueur :
                        sendToURL(new URLRequest("http://neamar.fr/Res/AGraphe/Player.php"));

                        Fond = GetLevelData(NumeroNiveauActuel);//Charger le niveau de numéro NumeroNiveauActuel
                        addChild(Fond);
                        Fond.graphics.clear();//enlever le fond blanc que les niveaux ont normalement.
                        Fond.FlouFinal=Fond.FLOU_FINAL;

                        //Repasser la boite de message au premier plan...c'est plus pratique pour la lire :-)
                        setChildIndex(Fond,1);//Sinon, Fond est au 1er plan et bloque la lecture des informations.
                        addEventListener(Event.ENTER_FRAME,TesterFinNiveau);


                        ////////////////////////////////
                        //Les éléments inclassables
                        ////////////////////////////////
                        function SourisIN(e:Event):void
                        {//Fonction Utilisée sur tous les sprites de type bouton : ajoute un filtre au Sprite afin de l'illuminer
                                AppliquerFiltre(e.currentTarget)
                        }
                        function SourisOUT(e:Event):void
                        {//Fonction Utilisée sur tous les sprites de type bouton : retire les filtres du Sprite
                                e.currentTarget.filters=new Array();
                        }
                        function AppliquerFiltre(Element:Sprite,Couleur:uint=0x000000):void
                        {//Ajoute un filtre de rayonnement à l'objet spécifié
                                var FiltreHover:BitmapFilter = new GlowFilter(Couleur, 0.8,16,16,3,1,false,false);
                                var ListeFiltres:Array = new Array();
                                ListeFiltres.push(FiltreHover);
                                Element.filters=ListeFiltres;
                        }
                        function SwapBackGround():void
                        {//Télecharger l'image de fond, l'afficher.
                                //Le Img_FondContext  sert à demander le télechargement du fichier crossdomain.xml
                                Img_Fond.load(new URLRequest("http://neamar.fr/Res/AGraphe/Images/Fond.png"),new LoaderContext(true));
                                if(!contains(Img_Fond))
                                {//Et la mettre au dernier plan
                                        addChild(Img_Fond);
                                        setChildIndex(Img_Fond,0);
                                }
                        }
                        function ResetAll(e:Event):void
                        {
                                NumeroNiveauActuel=NumeroNiveauUnlockes=SESSION.NumeroNiveauActuel=SESSION.NumeroNiveauUnlockes=0;
                                UpdaterBoite();
                        }
                }
        }
}
 
Code source : ChangementsNiveaux.as
  • Langage : actionscript3
  • ΔT : 0.065s
  • Taille :3268 caractères
/////////////////////////////////////
//Fonctions utilisées en cours de niveau
/////////////////////////////////////
function TesterFinNiveau(e:Event):void
{//Teste si le niveau est terminé, ou si il est invalide.
//Fonctionne aussi quand le mode 2 joueurs est activé.
        if(Mode2Joueurs)
                Verifier_2Joueurs();
        else
        {
                if(GrandPere.Ferme)
                        TerminerNiveau(1);//GAGNÉ !
                else
                {
                        if(Fond.NbJetonsToleres-Fond.NbJetonsUtilises<0)
                        {//PERDU
                                TerminerNiveau(0);
                                ChangeLevelInfo.htmlText="<b>Trop de noeuds allumés !</b>";
                        }
                }
        }
}

/////////////////////////////////////
//Fonctions utilisées lors des changements de niveaux
/////////////////////////////////////
function TerminerNiveau(Valeur:int):void
{//Termine un niveau en affichant la boite de changement
//Ajoute la valeur aux niveaux unlockés.
        removeEventListener(Event.ENTER_FRAME,TesterFinNiveau);

        Flouter(Fond,0,Fond.FLOU_FINAL);//Ajouter un flou

        NumeroNiveauActuel+=Valeur;
        if(NumeroNiveauActuel>NumeroNiveauUnlockes && Fond.Officiel==true && NumeroNiveauActuel<12)
        {//Si il vient de réussir le niveau sur lequel il était bloqué
                NumeroNiveauUnlockes+=Valeur;//Débloquer un nouveau niveau
                SESSION.NumeroNiveauActuel=NumeroNiveauActuel;//Et enregistrer en local la progression
                SESSION.NumeroNiveauUnlockes=NumeroNiveauUnlockes;
                ChangeLevelInfo.htmlText="Nouveau Niveau débloqué !";
        }

        //Puis afficher la boite avec la liste des niveaux.
        UpdaterBoite();
}

function StopLevel(e:Event=null):void
{//Arrête le niveau directement.
        TerminerNiveau(0);
        Message_Container.visible=false;
        ChangeLevelInfo.htmlText="<b>Niveau abandonné !</b>";
}

function LancerNouveauNiveau(NumNiveau:int=-1):void
{//Lancer un niveau "quelconque"
        if(NumNiveau==-1)
                NumNiveau=NumeroNiveauActuel;

        if(Fond!=null && contains(Fond))
        {//Si Fond a déjà été utilisé, nettoyer l'ensemble
                Fond.Nettoyer();
                removeChild(Fond);
        }


        //SwapBackGround();
        Fond = GetLevelData(NumNiveau);
        Fond.graphics.clear();//Supprimer le fond blanc
        addChild(Fond);
        //Repasser la boite de message au premier plan
        setChildIndex(Fond,1);

        Flouter(Fond,Fond.FLOU_FINAL,0);//Déflouter

        addEventListener(Event.ENTER_FRAME,TesterFinNiveau);
        ChangeLevelInfo.htmlText="<u>Liste des niveaux</u>";
}

////////////////////////////////////////
//Partie gérant les effets graphiques
////////////////////////////////////////
function Flouter(Layer:Niveau,Depart:int,Arrivee:int):void
{
        Layer.FlouFinal=Arrivee;
        Layer.Flou=Depart;
        Layer.addEventListener(Event.ENTER_FRAME,GererFlou);
}

function GererFlou(e:Event):void
{//Flouter le niveau en arrière plan
        var Layer:Object=e.currentTarget;
        if(Layer.Flou!=Layer.FlouFinal)
        {
                if(Layer.Flou<Layer.FlouFinal)
                        Layer.Flou+=2;
                else
                        Layer.Flou-=2;
                var FiltreFlou:BitmapFilter = new BlurFilter(Layer.Flou,Layer.Flou)
                var ListeFiltres:Array = new Array();
                ListeFiltres.push(FiltreFlou);
                Layer.filters=ListeFiltres;
                if(Layer.FlouFinal==0)
                {
                        Boite.alpha=Math.max(0,Layer.Flou/Layer.FLOU_FINAL);
                        if(Layer.Flou==0)
                                Boite.visible=false;
                }
                else
                {
                        Boite.visible=true;
                        Boite.alpha = Math.min(1,2*Layer.Flou/Layer.FlouFinal);
                }
        }
        else
        {
                Boite.visible=(Boite.alpha>.5);
                Layer.removeEventListener(Event.ENTER_FRAME,GererFlou);
        }
}
Code source : ChargementNiveaux.as
  • Langage : actionscript3
  • ΔT : 0.140s
  • Taille :7966 caractères
/////////////////////////////////////
//Fonctions de création de niveau
/////////////////////////////////////

function GetLevelData(Numero:int,Not_Mute:Boolean=true):Niveau
{
        const NIVEAUX_JETONS:Array=new Array(3,4,5,4,5,5,3,5,6,7,5,6);
        var Hook:Array=new Array(); //Vide la liste des Hook.
        var Non_Extinctible:Array=new Array(); //Vide la liste des Non_Extinctible.
        var Niveau_datas:Array; //Contient l'arborescence sous forme numérique
        var Inutile:Array=null;//Evite de réecrire complètement un niveau lors de sa modification
        var Message:String="";

        function T(...Liste):Array
        {//T comme Tableau
        //Plus court à écrire que new Array() à chaque fois
                return Liste;
        }
        if(Numero==0)
        {
                Niveau_datas=new Array(null,null,T(0,1));
                Message ="<u>Règles d'A-graphe : <font size=\"-2\"><i>(partie 1/3)</i></font></u><br><li><b>Règle n°1 : </b> Pour allumer un noeud (representé par un cercle), cliquer dessus.</li><li><b>Règle n°2 : </b> Pour terminer un niveau, allumer le noeud principal, centré en haut.</li><li><b>Règle n°3 : </b> Un noeud est allumable si et seulement si tous ses enfants (les noeuds qui descendent de lui) sont allumés.</li>";
        }

        else if(Numero==1)
        {
                Niveau_datas=new Array(null,null,null,T(0,1,2),null,null,T(4,5),T(3,6));
                Message = "<u>Règles d'A-graphe : <font size=\"-2\"><i>(partie 2/3)</i></font></u><br><li><b>Règle n°4 : </b> Il est interdit d'allumer simultanément plus de noeuds que le nombre imparti pour chaque niveau (ce nombre est affiché en haut, à droite).</li><li><b>Règle n°5 : </b> Une fois un noeud allumé, on peut éteindre ses enfants sans que cela éteigne le parent.</li>";
        }
        else if(Numero==2)
        {
                Niveau_datas=new Array(null,null,T(0,1),null,null,T(1,3,4),null,T(4,6),null,T(8),T(9),T(2,5,7,10));
                Message = "<u>Règles d'A-graphe : <font size=\"-2\"><i>(partie 3/3)</i></font></u><br><li><b>Règle n°6 : </b> Un noeud allumé puis éteint ne peut pas être rallumé.</li><li><b>Règle n°7 : </b> Les noeuds marqués d'une croix ne peuvent pas être éteints.</li><br>Voilà, c'est tout pour les règles. Bonne chance !";
        }
        else if(Numero==3)
                Niveau_datas=new Array(null,null,null,T(0),T(3,2),T(1,0),T(5,0,4));
        else if(Numero==4)
        {
                Niveau_datas=new Array( null,null,null,T(0,1,2),null,null,T(4,5),T(3,6),null,null,T(8,9),null,null,T(11,12),null,null,T(14,15),T(10,13,16),null,T(17,18),T(7,19));
        }
        else if(Numero==5)
        {
                Niveau_datas=new Array(null,null,null,T(0),T(0,2),T(2),T(3,4,5),T(1),T(3,4,5),T(6,7,8));
                Hook[1]=1;
                Message = "<li><b>Dernier niveau du tutorial.</b> Les choses vont rapidement se gâter ! Bonne chance pour la suite...</li><li>Un conseil avant de nous quitter : pensez à bien vérifier l'agencement des noeuds avant de commencer : certains sont un peu traîtres...</li>";
        }
        else if(Numero==6)
        {
                Niveau_datas=new Array(null,T(0),null,null,T(3),T(2,3),T(4),T(5,6),T(1,7));
                Hook[3]=-1;
        }
        else if(Numero==7)
        {
                Niveau_datas=new Array(null,T(0),T(0),T(0),T(1),T(1,2),T(2,3),T(3),T(4,5),T(5,6,7),T(8),null,T(9,11),T(10),T(12),T(13,14),T(13,15),T(14,11,7),T(16,15,17));
                //Hook[15]=-1;
                Non_Extinctible[7]=true;
        }
        else if(Numero==8)
        {
                Niveau_datas=new Array(null,T(0),null,T(0,2),T(1),T(4),T(1,0),T(3,2),T(5,4),null,null,null,T(9,10),T(10,11),T(12),T(13),T(14),T(15),T(12),T(13),T(10),T(16,18,20,19,17),T(6,7,8),T(21,22));
        }
        else if(Numero==9)
                Niveau_datas=new Array(null,T(0),T(0),T(1),T(1,0),T(2,0),T(2),T(3),T(3,1,4),T(5,6),T(6),T(7,3,8),T(9,10),T(11,8,4,5,9,12));
        else if(Numero==10)
                Niveau_datas=new Array(null,null,null,null,T(0,1),T(2,3),T(4),T(4),T(5),T(5),T(6),T(6,7),T(7),T(8),T(9),T(10,11,12),T(13,14),T(15),T(15,16),T(16),null,null,null,null,null,T(22,20,23),T(23,21,24),T(25,26),T(17,18),T(18,19),T(28,29),T(30,27));
        else if(Numero==11)
        {
                Niveau_datas=new Array(null,T(0),T(0),T(0),T(1,0),T(1,0,2),T(1,2,3),T(4,5,6),T(5,0,6),T(0,6),null,null,T(10),T(11),T(13,11),null,null,null,null,null,T(12),T(14),T(13,20),T(15,16,17,18),T(19,12,10),T(21,20),T(22,23,24),T(25),T(25),T(26,27),T(27),T(28),T(29),T(29,30),T(0,6,31,32,33),T(7,8,34));
                Message="<u>Dernier niveau</u><br>Je vous souhaiterais bien bonne chance, mais je crains que cela ne suffise pas ;-)";
        }

        if(Message!="" && Not_Mute && !Mode2Joueurs)
                ShowMessage(Message);
        if(Mode2Joueurs)
                ShowMessage("<u>Niveau en mode 2 Joueurs</u><li>Les informations du niveau sont affichées en haut, à droite.</li><li>N'oubliez pas que vous pouvez éteindre des noeuds ! Votre tour ne se finit que quand vous en allumez un.</li>");

        return LoadNiveau(Niveau_datas,Numero.toString(),NIVEAUX_JETONS[Numero],Hook,Non_Extinctible);
}

function String2Level(Niv_String:String,Titre:String="Mon niveau perso",NbJetons:int=5):Niveau
{//Crée un niveau à partir d'un string.
//Utilisé en mode 2 joueurs, mais aussi lors de la résolution automatique d'un niveau.
        var Hook:Array=new Array(); //Vide la liste des Hook.
        var Non_Extinctible:Array=new Array(); //Vide la liste des Non_Extinctible.
        var Allumes:Array=new Array();
        var DejaAllumes:Array=new Array();
        var i:int=0;
        var Niv_Array:Array=Niv_String.split(",");
        function ReplaceNullItem(T:Array):void
        {

                if(T.length>1)
                {
                        for(var j:int=0;j<T.length;j++)
                        {//On ne peut pas utiliser for each, car String est un type primitif : on agirait sur une copie de l'objet.
                                if(T[j]=="null")
                                        T[j]=null;
                        }
                }
        }


        for(i=0;i<Niv_Array.length;i++)
        {//Trouver les Hook, les allumés et les non exctinctibles.
                if(Niv_Array[i]!=Niv_Array[i].replace("X",""))
                {//ajouter NonExtinctible
                        Niv_Array[i]=Niv_Array[i].replace("X","");
                        Non_Extinctible[i]=true;
                }
                if(Niv_Array[i]!=Niv_Array[i].replace("@",""))
                {//ajouter NonExtinctible
                        Niv_Array[i]=Niv_Array[i].replace("@","");
                        Allumes[i]=true;
                }
                if(Niv_Array[i]!=Niv_Array[i].replace("-",""))
                {//ajouter un Hook
                        Niv_Array[i]=Niv_Array[i].replace("-","");
                        Hook[i]=-1;
                }
                if(Niv_Array[i]!=Niv_Array[i].replace("+",""))
                {//ajouter un Hook
                        Niv_Array[i]=Niv_Array[i].replace("+","");
                        Hook[i]=1;
                }
                if(Niv_Array[i]!=Niv_Array[i].replace("!",""))
                {//ajouter un Hook
                        Niv_Array[i]=Niv_Array[i].replace("!","");
                        DejaAllumes[i]=true;
                }
        }
        //Remplacer "null" par...le vrai null
        ReplaceNullItem(Niv_Array);

        for(i=0;i<Niv_Array.length;i++)
        {//On ne peut pas utiliser for each, car String est un type primitif
                if(Niv_Array[i]!=null && Niv_Array[i].indexOf("/")!=-1)
                {
                        Niv_Array[i]=Niv_Array[i].split("/");
                        Niv_Array[i].pop();//Supprimer le dernier item, qui est null
                        ReplaceNullItem(Niv_Array[i]);
                }
        }
        return LoadNiveau(Niv_Array,Titre,NbJetons,Hook,Non_Extinctible,Allumes,DejaAllumes);
}

function ChargementNiveauDirect(e:Event):void
{//Triggeré quand clic sur une des miniatures dans Boite.
        while(Boite.numChildren > 0)
                Boite.removeChildAt(0);

        Boite.addChild(ChangeLevelInfo);

        ChangeLevelInfo.htmlText="<u>Chargement en cours</u> (niv. <b>"+e.currentTarget.NumeroNiveau+"</b>)";
        if(e.currentTarget.Officiel)
        {
                NumeroNiveauActuel=e.currentTarget.NumeroNiveau;
                LancerNouveauNiveau(e.currentTarget.NumeroNiveau);
        }
        else
                LancerChargement();
}


function LoadNiveau( Level:Array,NumNiveau:String,NBJetons:int,Hook:Array,Non_Extinctible:Array,Allumes:Array=null,DejaAllumes:Array=null):Niveau
{//La fonction principale, qui charge le niveau dans un sprite
        var Layer:Niveau; //Layer est le Sprite qui doit contenir le niveau
        if(Allumes==null)
                Allumes=new Array();
        if(DejaAllumes==null)
                DejaAllumes=new Array();
        Layer=new Niveau(NumNiveau,Level,Hook,Non_Extinctible,Allumes,DejaAllumes,NBJetons,FlashHeight,FlashWidth,Mode2Joueurs);
        GrandPere=Layer.All_Noeuds[Level.length-1];
        //Puis régler les positions Y.
        //Pour cela, il faut d'abord trouver le nombre d'imbrications.
        //Facile ! Il suffit d'appeler GrandPere.Profondeur(), qui est récursive.
        GrandPere.GererXY(1,GrandPere.Profondeur(),FlashWidth-20,FlashWidth/2 -10);
        GrandPere.RecreerArbreLien();
        Layer.CreerArbreParents(GrandPere);
        return Layer;
}
Code source : Message.as
  • Langage : actionscript3
  • ΔT : 0.124s
  • Taille :7918 caractères

//Déclaration des Sprites
var Boite:Sprite = new Sprite();
var RetryLevelButtonInterne:Sprite;
var Annuler_Choix:Sprite;
var Neamar_Sprite:Sprite;

var Message_Container:Sprite=new Sprite();
var Message_TexteOK:Sprite=new Sprite();
var Mods:Sprite=new Sprite();
var LVL_En_Cours:Niveau;
var LVL_Edit:Niveau=null;

//Remplissage des Sprites

Message_Container.graphics.beginFill(0x444444);
Message_Container.graphics.lineStyle(2,0x000000);
Message_Container.graphics.drawRect(0, 0,440,140);
Message_Container.x=100;
Message_Container.y=160;
Message_Container.visible=false;
Message_Container.alpha=.8;

var Message_Texte:TextField = CreerTextField(Message_Container,10,10,420,100);

Message_TexteOK = LevelChangeButton(0);
Message_TexteOK.scaleX=Message_TexteOK.scaleY=.3;
Message_Container.addChild(Message_TexteOK);
Message_TexteOK.x=420;
Message_TexteOK.y=120;
Message_TexteOK.addEventListener(MouseEvent.CLICK,RemoveMessage);


Boite.graphics.beginFill(0xCCCCCC);
Boite.graphics.lineStyle(1,0x000000);
Boite.graphics.drawRect(0, 0,240,180);
Boite.x=50;
Boite.y=50;
Boite.width=FlashWidth-100;
Boite.height=FlashHeight-100;
Boite.visible=false;
addChild(Boite);
AppliquerFiltre(Boite);

Annuler_Choix=LevelChangeButton(180);
Annuler_Choix.scaleX=Annuler_Choix.scaleY=0.15;
Annuler_Choix.addEventListener(MouseEvent.CLICK,Annuler);

addChild(Message_Container);
AppliquerFiltre(Message_Container);


var ChangeLevelInfo:TextField = CreerTextField(Boite,30,0,FlashWidth-100,25,false,false,false);
ChangeLevelInfo.htmlText="<u>Liste des niveaux</u>";


RetryLevelButtonInterne=LevelChangeButton(90);
addChild(RetryLevelButtonInterne);
RetryLevelButtonInterne.x=640;
RetryLevelButtonInterne.y=450;
RetryLevelButtonInterne.scaleX=RetryLevelButtonInterne.scaleY=.2;
RetryLevelButtonInterne.addEventListener(MouseEvent.CLICK,StopLevel);


Neamar_Sprite = new Sprite();
Neamar_Sprite.graphics.beginFill(0xCCCCCC);
Neamar_Sprite.graphics.drawRect(0, 0, 640, 480);
Neamar_Sprite.graphics.endFill();
Neamar_Sprite.graphics.lineStyle(2,0x000000);
Neamar_Sprite.graphics.lineTo(640,0);
Neamar_Sprite.graphics.lineTo(340,220);
Neamar_Sprite.graphics.moveTo(0,0);
Neamar_Sprite.graphics.lineTo(320,220);
Neamar_Sprite.graphics.moveTo(320,260);
Neamar_Sprite.graphics.lineTo(0,480);
Neamar_Sprite.graphics.lineTo(640,480);
Neamar_Sprite.graphics.lineTo(360,260);
Neamar_Sprite.graphics.drawCircle(320, 240,120);
Neamar_Sprite.width=640;
Neamar_Sprite.height=480;
Neamar_Sprite.scaleX=Neamar_Sprite.scaleY=0.07;
AppliquerFiltre(Neamar_Sprite);
Neamar_Sprite.addEventListener(MouseEvent.MOUSE_OVER,APropos);
Neamar_Sprite.addEventListener(MouseEvent.CLICK,AProposTexte);

Mods.graphics.beginFill(0xCCCCCC);
Mods.graphics.drawRect(0, 0, 100,30);
Mods.graphics.endFill();
AppliquerFiltre(Mods);

//Ajout dans Mods
var SpriteReset:Sprite=new Sprite();
var Mods_Reset:TextField = CreerTextField(SpriteReset,0,0,180,20,false,false,false);
Mods_Reset.htmlText="<li>RESET</li>";
SpriteReset.scaleX=SpriteReset.scaleY=0.4;
SpriteReset.y=16;
Mods.addChild(SpriteReset);

SpriteReset.addEventListener(MouseEvent.MOUSE_OVER,SourisIN);
SpriteReset.addEventListener(MouseEvent.MOUSE_OUT,SourisOUT);
SpriteReset.addEventListener(MouseEvent.CLICK,ResetAll);

//Lien vers http://www.mini-jeu-gratuit.fr/
var SpriteSponsor:Sprite=new Sprite();

var Mods_Sponsor:TextField=CreerTextField(SpriteSponsor,0,0,50,35,false,true,false)
Mods_Sponsor.htmlText="<a href=\"http://www.mini-jeu-gratuit.fr/vip/neamar/\" target=\"_blank\">Plus de jeux</a>";
// SpriteSponsor.addEventListener(MouseEvent.MOUSE_MOVE,SourisIN);
// SpriteSponsor.addEventListener(MouseEvent.MOUSE_OUT,SourisOUT);



function CreerTextField(Parent:Sprite,x:int,y:int,width:int,height:int,multiline:Boolean=true, selectable:Boolean=false,border:Boolean=true):TextField
{//Instanciateur de TextField
        var TextFieldTemporaire:TextField=new TextField();
        Parent.addChild(TextFieldTemporaire);
        TextFieldTemporaire.x=x;
        TextFieldTemporaire.y=y;
        TextFieldTemporaire.width=width;
        TextFieldTemporaire.height=height;
        TextFieldTemporaire.wordWrap=true;
        TextFieldTemporaire.background =TextFieldTemporaire.border=border;
        TextFieldTemporaire.multiline=multiline;
        TextFieldTemporaire.selectable=selectable;
        return TextFieldTemporaire;
}

function LevelChangeButton(Angle:int):Sprite
{//fonction qui génére un bouton de type "Suivant".
        var LevelChangeButtonSprite:Sprite=new Sprite();
        LevelChangeButtonSprite.graphics.beginFill(0x7F7FB3);
        LevelChangeButtonSprite.graphics.lineStyle(1,0x000000);
        LevelChangeButtonSprite.graphics.drawCircle(75,75,75)
        LevelChangeButtonSprite.graphics.endFill();
        LevelChangeButtonSprite.graphics.lineStyle(10,0xFF0000);
        LevelChangeButtonSprite.graphics.moveTo(33,33);
        LevelChangeButtonSprite.graphics.lineTo(116,75);
        LevelChangeButtonSprite.graphics.lineTo(33,117);
        LevelChangeButtonSprite.rotation=Angle;
        LevelChangeButtonSprite.alpha=1;
        LevelChangeButtonSprite.addEventListener(MouseEvent.MOUSE_MOVE,SourisIN);
        LevelChangeButtonSprite.addEventListener(MouseEvent.MOUSE_OUT,SourisOUT);
        return LevelChangeButtonSprite;
}

function ShowMessage(Texte:String):void
{//Affiche un message.
        Message_Container.visible=true;
        Message_Texte.htmlText=Texte;
}
function RemoveMessage(e:Event=null):void
{//Cache la boite de messages
        Message_Container.visible=false;
}

function UpdaterBoite():void
{
        function Afficher(Image:Niveau,Empl:int):void
        {
                Boite.addChild(Image);
                Image.scaleX=Image.scaleY=0.07;
                Image.x=15 + (Empl%4)*Ecart;
                Image.addEventListener(MouseEvent.MOUSE_OVER,SourisIN);
                Image.addEventListener(MouseEvent.MOUSE_OVER,AfficherInfos);
                Image.addEventListener(MouseEvent.MOUSE_OUT,SourisOUT);
                Image.addEventListener(MouseEvent.CLICK,ChargementNiveauDirect);
                Image.y=20 + Math.floor(Empl/4)*Ecart/1.3;
        }

        RemoveMessage();
        //Générer un préview des niveaux
        while(Boite.numChildren > 0)
                Boite.removeChildAt(0);

        var Ecart:Number=Boite.width/10;
        for(var i:int=0;i<=NumeroNiveauUnlockes;i++)
        {
                var ThumbShot:Niveau=GetLevelData(i,false);//true indique qu'il ne faut pas afficher les messages;
                Afficher(ThumbShot,i);
                Boite.addChild(ThumbShot);
                if(i==NumeroNiveauActuel)
                        AppliquerFiltre(ThumbShot,0x7F7FB3)
        }

        if(LVL_Edit!=null)//LVL_Edit est mis à jour lors du chargement d'un niveau perso
                Afficher(LVL_Edit,14);
        else
        {
                Boite.addChild(SpriteSponsor);
                SpriteSponsor.x=15+2*Ecart;
                SpriteSponsor.y=20+3*Ecart/1.3;
                SpriteSponsor.filters=new Array(new BevelFilter(7,90,0x7F7F00,1,0x000000,1,10,4,10));
        }

        Boite.addChild(Annuler_Choix);
        Annuler_Choix.y=16;
        Annuler_Choix.x=16;
        Boite.addChild(ChangeLevelInfo);
        Boite.addChild(Neamar_Sprite);
        Neamar_Sprite.x=17 + 3*Ecart;
        Neamar_Sprite.y=20 + 3*Ecart/1.3;

        Boite.addChild(Mods);
        Mods.x=15;
        Mods.y=20 + 3*Ecart/1.3;

}

function AfficherInfos(e:Event):void
{
        ChangeLevelInfo.htmlText="Charger le niveau <b>"+e.currentTarget.NumeroNiveau +"</b>";
        if(e.currentTarget.NumeroNiveau==NumeroNiveauUnlockes)
                ChangeLevelInfo.htmlText="Dernier niveau débloqué : <b>"+e.currentTarget.NumeroNiveau +"</b>";
        if(e.currentTarget.NumeroNiveau==NumeroNiveauActuel)
        {
                ChangeLevelInfo.htmlText="Dernier niveau tenté : <b>"+e.currentTarget.NumeroNiveau +"</b>";
                AppliquerFiltre(e.currentTarget,0x7F7FB3)
        }
}
function APropos(e:Event):void
{
        ChangeLevelInfo.htmlText="Informations, explications, code source...";
}

function AProposTexte(e:Event):void
{
        ShowMessage("<u>À propos...</u><br><li>Jeu réalisé par Neamar en AS3 libre.</li><li>Explications du jeu, dernières mises à jour, code source, aide à la compilation : <a href=\"http://neamar.fr/Res/AGraphe/\" target=\"_blank\">http://neamar.fr/Res/AGraphe (click to go)</a></li>");
}

function Annuler(e:Event):void
{
        Flouter(Fond,Fond.FLOU_FINAL,0);//Déflouter
        GrandPere=Fond.All_Noeuds[Fond.All_Noeuds.length-1];//Remettre le bon GrandPere !
        addEventListener(Event.ENTER_FRAME,TesterFinNiveau);
}

Fichiers de mod

Code source : 2Joueurs.as
  • Langage : actionscript3
  • ΔT : 0.039s
  • Taille :2065 caractères

//Les variables utiles :
var Mode2Joueurs:Boolean=false;

var SVGNbJetons:int=-1;
var TourDuJoueur:int=1;


//Les sprites du Mods
var Sprite2Joueurs:Sprite=new Sprite();

var Mods_2Joueurs:TextField=CreerTextField(Sprite2Joueurs,0,0,180,25,true,false,false);
Mods_2Joueurs.htmlText="<li>Activer le mode \"2 Joueurs\"</li>";


Sprite2Joueurs.scaleX=Sprite2Joueurs.scaleY=0.4;
Mods.addChild(Sprite2Joueurs);
Sprite2Joueurs.addEventListener(MouseEvent.MOUSE_OVER,SourisIN);
Sprite2Joueurs.addEventListener(MouseEvent.MOUSE_OUT,SourisOUT);
Sprite2Joueurs.addEventListener(MouseEvent.CLICK,SwapMode);

function SwapMode(e:Event):void
{//passe du mode 1 joueur au mode 2 joueurs et vice versa
        Mode2Joueurs=! Mode2Joueurs;
        UpdaterBoite();
        if(Mode2Joueurs)
        {
                Mods_2Joueurs.htmlText="<li>Désactiver le mode \"2 Joueurs\"</li>";
                ShowMessage("<u>Mode 2 Joueurs</u> : Le mode 2 Joueurs se joue sur les mêmes niveaux que le mode normal. En voici les règles :<li>Chacun votre tour, il faut allumer un noeud. Avant d'allumer un noeud, vous pouvez en éteindre autant que vous le souhaitez ;</li><li>Le perdant est celui qui ne peut plus allumer de noeuds.</li>Les règles sont simples, à vous de bloquer l'adversaire !<br>Que le meilleur gagne...");
        }
        else
                Mods_2Joueurs.htmlText="<li>Activer le mode \"2 Joueurs\"</li>";

        if(contains(Fond))
                removeChild(Fond);
}

function Verifier_2Joueurs():void
{//Changmeent de tours, et vérification pour savoir si la partie est terminée
        var NbNoeudsPossible:int;
        if(SVGNbJetons<Fond.NbJetonsUtilises)
                TourDuJoueur=(TourDuJoueur+1)%2;

        //Tester si gagné ou perdu :
        NbNoeudsPossible=0;
        for each(var Enfant:Noeud in Fond.All_Noeuds)
        {//Vérifier que tous les enfants sont bien fermés
                if(Enfant.Peut_Etre_Allume())
                        NbNoeudsPossible++;
        }
        if(NbNoeudsPossible==0)
                Fond.Informations.htmlText="<b>Joueur "+(TourDuJoueur+1)+" a perdu !</b>";
        else
                Fond.Informations.htmlText="Tour de Joueur <b>"+(TourDuJoueur+1)+"</b> ("+NbNoeudsPossible+" choix)";

        //Mettre à jour la sauvegarde
        SVGNbJetons=Fond.NbJetonsUtilises;
}
Code source : Persos.as
  • Langage : actionscript3
  • ΔT : 0.047s
  • Taille :3501 caractères
//Ajout dans Mods
var SpritePerso:Sprite=new Sprite();
var Mods_Perso:TextField = CreerTextField(SpritePerso,0,0,180,20,false,false,false);
Mods_Perso.htmlText="<li>Éditeur de niveaux</li>";
SpritePerso.scaleX=SpritePerso.scaleY=0.4;
SpritePerso.y=8;
Mods.addChild(SpritePerso);

SpritePerso.addEventListener(MouseEvent.MOUSE_OVER,SourisIN);
SpritePerso.addEventListener(MouseEvent.MOUSE_OUT,SourisOUT);
SpritePerso.addEventListener(MouseEvent.CLICK,ShowLoadLevel);


//Graphismes de la boite
var LoadLevel:Sprite=new Sprite();
LoadLevel.graphics.beginFill(0x444444);
LoadLevel.graphics.lineStyle(2,0x000000);
LoadLevel.graphics.drawRect(0, 0,440,140);
LoadLevel.x=100;
LoadLevel.y=160;
LoadLevel.visible=false;
LoadLevel.alpha=.95;

var LoadLevelTexte:TextField = CreerTextField(LoadLevel,20,110,360,20,false,true);
LoadLevelTexte.type="input";
LoadLevelTexte.restrict="null,/@+-X0-9";
LoadLevelTexte.text="null,null,0/1/,2/,null,null,4/5/,3/6/";

var LoadLevelNb_Jetons:TextField = CreerTextField(LoadLevel,390,110,20,20,false,true);
LoadLevelNb_Jetons.type="input";
LoadLevelNb_Jetons.restrict="0-9";
LoadLevelNb_Jetons.text="4";

var LoadLevelCaption:TextField = CreerTextField(LoadLevel,20,10,400,100,true,true,false);

var Lancer_Level:Sprite=LevelChangeButton(0);
Lancer_Level.scaleX=Lancer_Level.scaleY=.3;
Lancer_Level.x=420;
Lancer_Level.y=90;
Lancer_Level.addEventListener(MouseEvent.CLICK,LancerChargement);
LoadLevel.addChild(Lancer_Level);

AppliquerFiltre(LoadLevel);

LoadLevelCaption.htmlText="<i>(Utilisez la roulette de la souris pour faire défiler le texte)<br>(<a href=\"http://neamar.fr/Res/AGraphe#Createur\" target=\"_blank\">http://neamar.fr/Res/AGraphe#Createur pour un tutorial plus clair</a>)<br><u>Éditeur de niveau</u><br>Un niveau est une simple chaine de caractères, les virgules délimitant des intervalles contenant un noeud chacun.<br>Un noeud sans enfant est noté null. Ainsi, pour réaliser un niveau avec un unique noeud, il faut simplement marquer <u>null</u> dans le champ de texte.<br>Pour les parents, il faut marquer le numéro d'intervalle des noeuds enfants, séparés par un / (slash). Ainsi, le premier niveau du jeu se code très simplement de la façon suivante : <u>null,null,0/1/</u> : deux enfants, et un parent qui réunit les deux.<br><b>Attention</b> : N'oubliez pas de mettre un slash à la fin de la liste !<br>Quelques astuces pour aller plus loin :<li>Vous pouvez marquer un noeud comme inextinctible en placant un X dans la liste : <u>nullX,null,0/1/X</u></li><li>Vous pouvez décaler l'affichage d'un noeud à l'aide de hook : + et -. Cela force l'affichage du noeud un cran plus haut (ou un cran moins haut). Par exemple, <u>null,null,0/1/+</u> affiche un niveau «en ligne».</li>";

addChild(LoadLevel);

function ShowLoadLevel(e:Event):void
{
        LoadLevel.visible=true;
        Boite.visible=false;
}


function LancerChargement(e:Event=null):void
{
        LoadLevel.visible=false;
        Boite.visible=false;
        Fond.filters=new Array();
        if(contains(Fond))
                removeChild(Fond);

        Fond=String2Level(LoadLevelTexte.text,"Niveau Perso",LoadLevelNb_Jetons.text);
        Fond.Officiel=false;
        addChild(Fond);
        Fond.graphics.clear();

        //Repasser la boite de message au premier plan...c'est plus pratique pour la lire :-)
        setChildIndex(Fond,1);
        addEventListener(Event.ENTER_FRAME,TesterFinNiveau);

        //Mettre à jour la preview
        LVL_Edit=String2Level(LoadLevelTexte.text,"Édition Actuelle",LoadLevelNb_Jetons.text);
        LVL_Edit.Officiel=false;
//      Trace("Nb :"+SolveLevel(Fond));
}
 

Classes

Code source : Niveau.as
  • Langage : actionscript3
  • ΔT : 0.088s
  • Taille :5069 caractères
//Un niveau standard : contient des liens et des noeuds !
package
{
        import flash.display.Sprite;
        import flash.geom.Point;
        import flash.display.Shape;
        import flash.events.*;
        import flash.text.TextField;

        public class Niveau extends Sprite
        {
                public var All_Noeuds:Array;//Contient l'arborescence sous forme de noeuds graphiques
                public var NbJetonsUtilises:int;
                public var NbJetonsToleres:int;
                public var NumeroNiveau:String;
                public var Mode2Joueurs:Boolean;
                public var Informations:TextField = new TextField();

                public var Flou:int=0;//Le niveau de flou du Fond actuel
                public const FLOU_FINAL:int=32;//Le niveau maximal de Flou, une constante.
                public var FlouFinal:int=FLOU_FINAL;//Le niveau final de flou demandé pour Fond.



                public var Officiel:Boolean=true;
                private var JetonsUtilises:Array;
                private var Layer:Sprite;
                private var GrandPere:Noeud;
                private var Niveau_Chiffre:Array;


                public function Niveau(NumeroNiveau:String,Niveau:Array,Hook:Array,Non_Extinctible:Array,Allumes:Array, DejaAllumes:Array, NbJetonsToleres:int, Hauteur:int,Largeur:int,Mode2Joueurs:Boolean)
                {
                        this.All_Noeuds = new Array();
                        this.NbJetonsToleres=NbJetonsToleres;
                        this.JetonsUtilises=new Array();
                        this.NumeroNiveau=NumeroNiveau;
                        this.Mode2Joueurs=Mode2Joueurs;
                        this.Niveau_Chiffre=Niveau;
                        var Enfants:Array;
                        var i:int;

                        All_Noeuds=new Array(Niveau.length);
                        for(i=0;i<Niveau.length;i++)
                        {
                                if(Niveau[i]!=null)
                                {
                                        Enfants=new Array();
                                        for each(var Enfant:int in Niveau[i])
                                        {
                                                Enfants.push(All_Noeuds[Enfant]);
                                        }
                                        All_Noeuds[i]=AjoutNoeud(Enfants)
                                }
                                else
                                        All_Noeuds[i]=AjoutNoeud(null);
                        }

                        //Les options supplémentaires:
                        //Hook
                        //Inextinguible
                        i=0;
                        for each(var Child:Noeud in All_Noeuds)
                        {
                                if(Hook[i]==null)
                                        Hook[i]=0;
                                if(Non_Extinctible[i]==null)
                                        Non_Extinctible[i]=false;
                                Child.addHook(Hook[i]);
                                Child.Is_Not_Eteignable(Non_Extinctible[i]);

                                if(Allumes[i]==true)
                                        Child.ChangeState(true,false);
                                if(DejaAllumes[i]==true)
                                        Child.aEteFerme=true;
                                i++;
                        }

                        //Nombre de jetons utilisables
                        for(i=0;i<NbJetonsToleres;i++)
                        {
                                JetonsUtilises[i]=new Noeud(new Array(),this);
                                if(!Mode2Joueurs)
                                        this.addChild(JetonsUtilises[i]);
                                JetonsUtilises[i].x=Largeur-(i+1)*25;
                                JetonsUtilises[i].y=15;
                                JetonsUtilises[i].scaleX=JetonsUtilises[i].scaleY=.5;
                        }

                        Informations.x = 500;
                        Informations.y = 0;
                        Informations.width=150;
                        Informations.height=20;
                        Informations.background = true;
                        Informations.border=true;
                        Informations.selectable=false;
                        if(Mode2Joueurs)
                                addChild(Informations);

                        this.graphics.beginFill(0xFFFFFF);
                        this.graphics.drawRect(0, 0, Largeur, Hauteur);
                        GrandPere=this.All_Noeuds[All_Noeuds.length-1];
                        UpdateNbJetons();//Si des noeuds sont allumés dès le départ, les compter

                }

                public function CreerArbreParents(NoeudActuel:Noeud):void
                {
                        for each(var Child:Noeud in NoeudActuel.Enfants)
                        {//Smells like recursivity again ;-)
                                Child.addParent(NoeudActuel);
                                CreerArbreParents(Child);
                        }
                }

                public function UpdateNbJetons():void
                {
                        var Comparaison:Boolean;
                        var Nb:int=0;
                        for each(var Child:Noeud in All_Noeuds)
                        {
                                if(Child.Ferme==true)
                                        Nb++;
                        }
                        this.NbJetonsUtilises=Nb;
                        for(var i:int=0;i<this.NbJetonsToleres;i++)
                        {
                                Comparaison=(i<this.NbJetonsUtilises);
                                JetonsUtilises[i].ChangeState(Comparaison,false);//Ne pas mettre à jour, sinon on a une réference infinie et stack overflow
                                if(Comparaison)
                                        JetonsUtilises[i].scaleX=JetonsUtilises[i].scaleY=.7;
                                else
                                        JetonsUtilises[i].scaleX=JetonsUtilises[i].scaleY=.5;
                        }
                }

                public function Niveau2String():String
                {//Renvoyer le niveau actuel sous la forme d'un string
                        var Level:String="";
                        for(var i:int=0;i<Niveau_Chiffre.length;i++)
                        {
                                var Child:Array=Niveau_Chiffre[i];
                                if(Child==null)
                                        Level +="null";
                                else
                                {
                                        for each(var BiChild:int in Child)
                                        {
                                                Level +=BiChild.toString()+"/";
                                        }
                                }
                                if(this.All_Noeuds[i].Ferme==true)
                                        Level+="@";
                                if(this.All_Noeuds[i].Peut_Eteint==false)
                                        Level+="X";
                                if(this.All_Noeuds[i].Hook_Y==-1)
                                        Level +="-";
                                if(this.All_Noeuds[i].Hook_Y==1)
                                        Level +="+";
                                if(this.All_Noeuds[i].aEteFerme==true)
                                        Level +="!";
                                Level +=",";
                        }
                        Level=Level.slice(0,Level.length-1);
                        return Level;
                }

                public function Nettoyer():void
                {
                        //Nettoyer le niveau
                        GrandPere.DeleteYourself();
                        All_Noeuds=new Array();
                        //Il y a un bug qui empêche la suppression des liens, donc on les vire manuellement.
                        while(this.numChildren > 0)
                        {
                                this.removeChildAt(0);
                        }
                }

                private function AjoutNoeud(Enfants:Array=null):Noeud
                {//Ajoute un noeud en mémoire, et retourne son occurence
                        if(Enfants==null)
                                Enfants=new Array();
                        var NouveauNoeud:Noeud=new Noeud(Enfants,this);
                        this.addChild(NouveauNoeud);
                        NouveauNoeud.x=NouveauNoeud.y=-20
                        return NouveauNoeud
                }
        }
}
Code source : Noeud.as
  • Langage : actionscript3
  • ΔT : 0.154s
  • Taille :8250 caractères
//Un noeud quelconque
package
{
        import flash.display.Sprite;
        import flash.geom.Point;
        import flash.events.*;
        import flash.filters.BitmapFilter;
        import flash.filters.GlowFilter;

        public class Noeud extends Sprite
        {
                public var Enfants:Array;//La liste des enfants
                public var Parents:Array;//idem pour les parents
                public var Ferme:Boolean;//Si le noeud est allumé, Ferme vaut true
                public var Hook_Y:int;
                public var Peut_Eteint:Boolean;//Les noeuds avec une croix à l'intérieur ont Peut_Eteint=false
                public var aEteFerme:Boolean;//Le noeud a déjà été allumé

                private const RAYON:int=15;
                private var Layer:Niveau;//Le sprite conteneur
                private var Arc_Liste:Array=new Array();//La liste des liens vers les enfants
                private var Final_Glow:int;//Le rayonnement du noeud
                private var Current_Glow:Number;//La valeur de rayonnement désirée
                private var NbPlacements:int;//Le nombre de fois que le noeud a été placé
                private const PI:Number=3.141;//...

                public function Noeud(Enfants:Array,Layer:Niveau)
                {//Instancie un nouveau noeud
                        this.Enfants = Enfants;
                        this.Parents=new Array();
                        this.Ferme=false;
                        this.aEteFerme=false;
                        this.Layer=Layer;
                        this.Final_Glow=this.Current_Glow=0;
                        this.NbPlacements=0; //Le nombre de fois que le noeud a été déplacé dans l'arbre, cf. fonction GererXY.
                        this.Hook_Y=0;
                        this.Peut_Eteint=true;

                        this.graphics.beginFill(0xEEEEEE);
                        this.graphics.lineStyle(1,0x000000);
                        this.graphics.drawCircle(0, 0, RAYON);

                        this.addEventListener(MouseEvent.MOUSE_MOVE,SourisIN);
                        this.addEventListener(MouseEvent.MOUSE_OUT,SourisOUT);
                        this.addEventListener(MouseEvent.CLICK,SourisClick);

                        RecreerArbreLien();
                }

                public function RecreerArbreLien():void
                {//Recrée l'ensemble des liens
                        //D'abord les supprimer proprement
                        RemoveLiens();
                        var Lien:Arc;
                        //Et refaire l'ensemble
                        for each(var Child:Noeud in Enfants)
                        {
                                Lien=new Arc(new Point(this.x,this.y),new Point(Child.x,Child.y));
                                Arc_Liste.push(Lien);
                                Layer.addChild(Lien);
                                Layer.setChildIndex(Lien,0);
                                //Ne pas oublier d'informer l'enfant que l'on a refait l'arbre :
                                Child.RecreerArbreLien();
                        }
                }

                public function Profondeur():int
                {//Renvoie la profondeur de l'objet, i.e le nombre maximal de sous enfants disponibles.
                        //Utilise la récursivité en faisant appel à ses enfants.
                        var Max:uint=0;
                        if(this.Enfants.length==0)
                                return 1;
                        else
                        {
                                for each(var Child:Noeud in Enfants)
                                {
                                        Max=Math.max(Max,Child.Profondeur());
                                }
                                return 1+Max;
                        }
                }

                public function addParent(Parent:Noeud):void
                {//Ajoute un parent au noeud
                        this.Parents.push(Parent);
                }

                public function AddFocus(Level:int):void
                {//Ajoute un flou à la forme.
                        for each(var Enfant:Noeud in Enfants)
                        {//Demande aux enfants d'afficher un flou aussi, mais un peu plus faible
                                Enfant.AddFocus(Math.max(0,Level-1));
                        }

                        //Puis lancer l'animation
                        this.Final_Glow=Level;
                        this.addEventListener(Event.ENTER_FRAME,ChangeFiltre);
                }

                public function addHook(Level:int):void
                {
                        this.Hook_Y=Level;
                }

                public function Is_Not_Eteignable(Valeur:Boolean):void
                {
                        this.Peut_Eteint=! Valeur;
                        if(Valeur==true)
                        {
                                this.graphics.moveTo(-RAYON*Math.sin(PI/4),-RAYON*Math.sin(PI/4));
                                this.graphics.lineTo(RAYON*Math.sin(PI/4),RAYON*Math.sin(PI/4));
                                this.graphics.moveTo(-RAYON*Math.sin(PI/4),RAYON*Math.sin(PI/4));
                                this.graphics.lineTo(RAYON*Math.sin(PI/4),-RAYON*Math.sin(PI/4));
                        }
                }

                public function GererXY(NiveauActuel:int,NiveauMax:int,Largeur:int,Position:int):void
                {//Cette fonction a pour but de gérer l'agencement des noeuds dans le graphe.
                //Le noeud recoit des ordres : sa position y est determinée par son imbrication
                //Sa position X est determinée par la variable Position.
                //Largeur lui indique que tous ses enfants devront être dans un rectangle de Position-Largeur/2 à Position+Largeur/2.
                        var Child:Noeud; //Pour les boucles!
                        var FutureLargeur:Number=Largeur/this.Enfants.length;
                        var i:int=0;
                        var YDemande:int=20+400*(NiveauActuel-1)/(NiveauMax-1);//Le niveau Y des enfants
                        var DecalageYHook:int=400/(NiveauMax-1);//Une valeur de décalage de Y
                        var PositionInitialeXEnfants:int=Position-Largeur/2;

                        this.NbPlacements++;//Nombre de fois que l'on place le noeud. Si on le place plusieurs fois, il faut le centrer de façon à ce qu'il soit bien, et pour cela on a besoin d ela moyenne, donc du nombre de déplacements à prendre en compte.
                        this.x=(Position+(this.NbPlacements-1)*this.x)/this.NbPlacements; //Si il a déjà été placé auparavant, on le centre : un simple calcul de moyenne avec pondération.
                        this.y = Math.max(this.y,YDemande) + this.Hook_Y*DecalageYHook;//Sile noeud a déjà été placé, ne conserver que le y le plus élevé. Ajouter le Hook si besoin.

                        for each(Child in this.Enfants)
                        {//Smells like recursivity again ;-)
                                i++;
                                Child.GererXY(NiveauActuel+1,NiveauMax,FutureLargeur,PositionInitialeXEnfants + (i-.5)*FutureLargeur);
                        }
                }

                public function Peut_Etre_Allume():Boolean
                {//Ce noeud est il allumable ?
                        var unEnfantOuvert:Boolean=false;
                        for each(var Enfant:Noeud in Enfants)
                        {//Vérifier que tous les enfants sont bien fermés
                                if(!Enfant.Ferme)
                                        unEnfantOuvert=true;
                        }
                        return (!unEnfantOuvert && !this.aEteFerme && !this.Ferme); //Si le noeud a déjà été fermé, il ne peut pas être refermé.
                }

                public function Peut_Etre_Eteint():Boolean
                {//Ce noeud est-il éteignable ?
                        return (this.Ferme && this.Peut_Eteint);
                }

                public function ChangeState(Etat:Boolean,TriggerUpdate:Boolean=true):void
                {//Passer d'un état à un autre.
                        this.Ferme=Etat;
                        if(Etat)
                        {
                                this.addEventListener(Event.ENTER_FRAME,ChangeFiltre)
                                if(!this.Peut_Eteint)
                                        this.addEventListener(Event.ENTER_FRAME,Tourne);
                        }
                        else
                        {
                                this.aEteFerme=true;
                                this.filters=new Array();
                        }

                        //On peut demander à ne pas mettre à jour le niveau. Pratique dans le cas où on change juste les jetons indiquants le nombre de noeuds allumés :)
                        if(TriggerUpdate)
                                Layer.UpdateNbJetons();//Demander une MAJ du nombre de jetons
                }

                public function DeleteYourself():void
                {//Demande l'auto destruction du noeud et de ses enfants.
                        RemoveLiens();
                        for each(var Enfant:Noeud in Enfants)
                        {//Demander la destruction des enfants.
                                Enfant.DeleteYourself();
                        }
                        //Puis supprimer du niveau le noeud
                        if(Layer.contains(this))
                                Layer.removeChild(this);
                }


                //Fonctions privées
                private function SourisIN(e:MouseEvent):void
                {//Ajoute un filtre indiquant que la forme est hoverée
                        AddFocus(Profondeur());
                }
                private function SourisOUT(e:MouseEvent):void
                {//Ajoute le filtre indiquant que la forme n'est plus hoverée
                        AddFocus(0);
                }

                private function SourisClick(e:Event):void
                {//swapper l'état de ouvert à fermé ou vice versa.
                        if(Peut_Etre_Eteint())
                                this.ChangeState(false);//Eteindre le noeud
                        else if(Peut_Etre_Allume())
                                this.ChangeState(true);//L'allumer
                }

                private function Tourne(e:Event):void
                {//Fait tourner le noeud, modulo 360.
                        this.rotation=(this.rotation+1)%360;
                }

                private function ChangeFiltre(e:Event=null):void
                {//gestion des filtres dans le temps

                        //Filtre HOVER
                        if(Current_Glow<Final_Glow)
                                Current_Glow=Math.min(Final_Glow,Current_Glow+0.2);
                        else
                                Current_Glow=Math.max(Final_Glow,Current_Glow-0.1);

                        var ListeFiltres:Array = new Array(new GlowFilter(0xFF0000, 0.8,16,16,Current_Glow,1,false,false));

                        //Filtre FORME FERMEE
                        if(Ferme)
                        {
                                if(Peut_Eteint)
                                        ListeFiltres.push(new GlowFilter(0x00FF00, 1,16,16,2*Profondeur(),1,false,false));
                                else
                                        ListeFiltres.push(new GlowFilter(0xFEA900, 1,16,16,2*Profondeur(),1,false,false));
                        }

                        //Applications des filtres
                        for each(var Lien:Arc in Arc_Liste)
                                Lien.filters=ListeFiltres;

                        this.filters=ListeFiltres;

                        if(Current_Glow==Final_Glow)
                                this.removeEventListener(Event.ENTER_FRAME,ChangeFiltre);
                }

                private function RemoveLiens():void
                {//Supprime les images des liens entres noeuds.
                        var Lien:Arc;
                        for each(Lien in Arc_Liste)
                        {
                                if(Layer.contains(Lien))
                                        Layer.removeChild(Lien);
                        }
                        Arc_Liste=new Array();
                }
        }
}
Code source : Arc.as
  • Langage : actionscript3
  • ΔT : 0.019s
  • Taille :1419 caractères
//Un lien (arete, arc...peut importe le nom !)
//Rien de bien compliqué, si ce n'est la définition de la courbe de bézier lors de l'utilisation de curveTo.
package
{
        import flash.display.Shape;//Shape consomme moins de ressource que Sprite. En contrepartie, il ne peut pasz avoir d'enfants, et ne recoit pas d'évenements souris. Ca tombe bien, on en a pas besoin :)
        import flash.geom.Point;

        public class Arc extends Shape
        {
                public var Parent:Point;
                public var Enfant:Point;

                public function Arc(Parent:Point,Enfant:Point)
                {//Instancie un nouveau lien : prend en paramètre le parent et l'enfant (en fait, leurs coordonnées)
                        this.Parent=Parent;
                        this.Enfant=Enfant;
                        this.Refresh();
                }

                public function ChangeOrigine(Parent:Point):void
                {//Change l'origine du lien
                        this.Parent=Parent;
                        this.Refresh();
                }

                private function Refresh():void
                {//Redessine entièrement le lien. Cette méthode est utilisée lorsque l'un des noeuds se déplace||est déplacé
                        this.graphics.clear();
                        this.graphics.moveTo(this.Parent.x,this.Parent.y);
                        this.graphics.lineStyle(2,0x444444);
//                      this.graphics.lineTo(this.Enfant.x,this.Enfant.y);
                        this.graphics.curveTo(this.Enfant.x,this.Parent.y + (this.Enfant.y-this.Parent.y)/2, this.Enfant.x,this.Enfant.y);//Rien de bien méchant : on commence à dessiner sur le parent, puis on définit un point de controle à mi-chemin, et on va jusqu'à Enfant.
                }
        }
}

Bonus

En bonus, le fichier de résolution qui donne le nombre minimal de jetons à utiliser pour un niveau.
Attention, il n'est pas optimisé, et est particulièrement long à l'éxécution...nécessitera une fonction trace.

Code source : Resolution.as
  • Langage : actionscript3
  • ΔT : 0.038s
  • Taille :2246 caractères
function SolveLevel(Level:Niveau,MaxJetons:int=0,NbActions:int=0):int
{//Prend en paramètre un niveau, renvoie le nombre minimum de noeuds à allumer simultanément.
//Utilise la récursivité...
var Enfant:Noeud;//Variable utilisée dans les boucles
var Jetons_actuel:int; //Le nombre de jetons consommés au maximum pendant la résolution
var BestValue:int; //Le meilleur Jetons_actuel que l'on ait trouvé;
var HasMadeChange:Boolean=false;//Si il vaut false à la fin de l'étape 1, on arrete tout
var DernierParentTraite:Noeud=new Noeud(new Array(),null);

//D'abord, présenter quelques fonctions utiles :
        function Parents_Allumes(Element:Noeud, index:int, Tableau:Array):Boolean
        {//renvoie Vrai si l'élement a été fermé, ou est fermé.
                return (Element.Ferme || Element.aEteFerme)
        }

//Etape 0 : Si GrandPere est allumé, arrêter la recherche !
if(Level.All_Noeuds[Level.All_Noeuds.length-1].Ferme==true)
        return 0;

//Etape 1 : Eteindre tous les noeuds qui n'ont plus besoin d'être allumés
for each(Enfant in Level.All_Noeuds)
{
        if(Enfant.Ferme==true && Enfant.Parents.every(Parents_Allumes))
        {//Every effectue un test sur tous les parents : si ils ont tous été allumés, on peut éteindre ce noeud.
                Enfant.ChangeState(false);//Eteindre l'item
        }
}

//Etape 2 : Allumer tous les noeuds possibles, les passer à la fonction SolveLevel.
//Récuperer le plus petit résultat, et le renvoyer.
Jetons_actuel=1000;
BestValue=1000;
for each(Enfant in Level.All_Noeuds)
{
        if(Enfant.Peut_Etre_Allume() && DernierParentTraite != Enfant.Parents[0])
        {//L'allumer
                Enfant.ChangeState(true);
                Jetons_actuel=Math.max(Level.NbJetonsUtilises,MaxJetons);
                Jetons_actuel=Math.max(Jetons_actuel,SolveLevel(String2Level(Level.Niveau2String(),"Résolution"),Jetons_actuel,NbActions + 1)); //On est obligé de passer par un export en string, car sinon on agirait sur la copie originale...ce qui n'est pas idéal.
                //SolveLevel va nous renvoyer le nombre de jetons requis. On ne le garde que si il est intéressant ;)
                Enfant.ChangeState(false);
                Enfant.aEteFerme=false;
                HasMadeChange=true;
                DernierParentTraite=Enfant.Parents[0];
        }
        BestValue=Math.min(Jetons_actuel,BestValue);
}
if(!HasMadeChange)
        return 10000;//Renvoyer une grosse valeur !

return BestValue;
}
Auteur
Neamar
Date
Aout 2008
But
Finir le jeu
Voir aussi
Compiler l'AS3
Retour
Retour à AGraphe
Menu
Index des ressources

Chargement du sommaire...