Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Programmation > ActionScript / Flash / Flex > Effets 3D > Lecture du tutoriel

Effets 3D

Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Avatar
Auteur : heero78
Note : 17 / 20 (3 votes)
Visualisations : 11 273

Plus d'informations Plus d'informations
Hier je surfais sur la toile, à la recherche d'informations pour la création d'un moteur 3D, et je suis tombé sur quelques effets sympa, que j'ai essayé de reproduire.

Voilà ce que l'on va apprendre à réaliser dans ce tutoriel (il est bien évident qu'une fois le principe compris, c'est à vous de l'exploiter pour l'améliorer) :
http://heero.blog.free.fr/autres/menu3D.swf

Note : Ce tutoriel est destiné aux utilisateurs de Flash ayant un minimum de bases en ActionScript, je ne détaillerai donc pas tout.
Sommaire du tutoriel :
Icône du chapitre

Etape 1 : Création du document.

1) Créez un nouveau document flash : Fichier => nouveau => document Flash.

2) Modifiez les propriétés du document : Modification => document (ctrl+j).
Modifiez les dimensions (200px/200px) et la couleur de fond (noir).

3) Enregistrez votre document. (ça peut paraître idiot comme instruction mais c'est une excellente habitude à prendre croyez-moi. ;) )

Voilà, l'étape la plus difficile est finie... C'est une blague bien sûr. :lol:

Etape 2 : Création du clip.

1) Créez un nouveau movieClip : Insertion => Nouveau Symbole (ctrl+F8).
Puis modifiez les propriétés comme ci-dessous :
Image utilisateur

Note : L'identifiant nous servira plus tard pour créer des copies du clip sur la scène via l'Action Script.


2) Sur la première image du scénario (toujours dans la clip 'cercle'.), dessinez un cercle. (couleur du centre : gris, et couleur des contours : blanc.)
Enfin, modifiez ses dimensions (H : 50px / L : 50px), et ses coordonnées, pour que celui-ci se trouve centré (X : -25px / Y : -25px).
Image utilisateur

3) Insérez une 2ème image-clef (encore et toujours dans le clip 'cercle'), dans laquelle vous modifiez la couleur de fond du cercle (rouge par exemple).

4) Sur un la première image d'un nouveau calque, ajoutez le code suivant dans la fenêtre 'action' :
Code : Autre
1
stop(); // On stop la lecture en boucle.


Encore une fois il est important de sauvegarder votre travail.

Etape 3 : Le code.

1) Voilà, tous les éléments on été créés, il ne nous reste plus qu'à nous attaquer à la partie la plus 'difficile' de ce tuto : le code.
En effet, nous n'allons pas créer un véritable moteur 3D (ce qui, entre nous, est au-delà de mon niveau :p ) mais plutôt d'en simuler un.
Tout notre code sera placé sur la première image du scénario de la scène principale.

2) On commence par créer quelques variables sur lesquelles va se baser notre animation.
Code : Autre
1
2
3
4
5
6
7
var profondeur:Number = 1000;
var largeur:Number = 200; // ou Stage.width
var hauteur:Number = 200; // ou Stage.height
var centre_x:Number = 100; // ou largeur/2
var centre_y:Number = 100; // ou hauteur/2
var frein:Number = 5;
var interval:Number;

Ici on veut que l'animation prenne toute la taille du document, et que son centre soit aussi le centre de notre document.
Je vous rappelle que sur la scène principale, le point de coordonnées (0;0) est le coin supérieur-gauche de votre document.

La variable 'profondeur' va être l'une des bases les plus importantes de notre 'simulation' d'effet 3D.
Nous verrons plus tard l'utilité de la variable 'frein' (qui ne porte pas ce nom par hasard vous vous en doutez :) ).

3) On crée une liste de noms, vous pouvez les remplacer par n'importe quoi bien évidemment (ce seront les mots qui apparaîtront dans les cercles) :
Code : Autre
1
var tab_nom_1:Array = new Array("1","2","3","4","5","6","7","8","9","10");


4) Maintenant nous allons créer une fonction qui crée et place nos occurrences (les copies) du clip 'cercle' de la bibliothèque :

on crée la fonction 'creer_btns' à laquelle on passe 2 paramètres.
Le premier, 'chem1' sera l'adresse du clip conteneur de notre animation, dans notre exemple celle-ci aura pour valeur '_root' c'est-à-dire la racine de notre animation.
Le deuxième 'tab_nom' est un tableau contenant des noms (comme son nom l'indique ^^ ).
Code : Autre
1
2
3
function creer_btns(chem1:MovieClip, tab_nom:Array):Void {
    // les instructions de la fonction
}


Note : En programmation, il faut toujours essayer de nommer les variables judicieusement, pour qu'au premier coup d'?il on sache vaguement ce qu'elles contiennent, ainsi notre variable 'tab_nom' est le diminutif de 'tableau_de_noms', ce qui se passe d'explications.


Ensuite on crée une boucle 'For' qui va créer autant de clips que de lignes dans le tableau 'tab_nom' (pour obtenir le nombre de lignes on utilise la méthode : monTableau.length).
Code : Autre
1
2
3
4
var taille:Number = tab_nom.length
for (var i:Number=0 ; i<taille ; i++) {
    // mes instructions
}


On va maintenant créer une variable qui nous servira à contenir le niveau de notre clip, celle-ci contiendra un nombre entre 1 et la valeur de la variable 'profondeur' (1000 dans notre cas).
Pour cela on utilise la méthode 'Math.random()' qui nous renvoie un nombre à virgule entre 0 et 1 que l'on multiplie par la valeur de la variable 'profondeur'. Et pour obtenir un nombre entier on utilise la méthode 'Math.round()' qui arrondit notre nombre à l'entier le plus proche.
Code : Autre
1
var var_profondeur:Number = Math.round(Math.random()*profondeur);


On crée un clip 'conteneur' vide, que l'on nomme en fonction de 'i' (si i=0 le clip sera nommé 'clip0', si i=1 => 'clip1' etc...)
Code : Autre
1
chem1.createEmptyMovieClip("clip"+i, var_profondeur);

Note : On remarque l'utilisation de 'chem1.' avant l'utilisation de la méthode de création du clip, cela signifie que l'on veut que le clip soit créé à l'intérieur du clip 'chem1' qui je vous le rappelle est l'un des paramètres envoyés à la fonction (dans notre cas ce sera '_root').


Lors de la création dynamique de plusieurs clips en fonction d'une variable, la modification des propriétés de ceux-ci nécessite de connaître leur nom. Ce qui à première vue n'est pas si facile que ça.
Ex : Soient plusieurs clips "clip+i", si i=5, on veut donc travailler uniquement sur le clip 'clip5', il est bien évident que l'on ne peut pas écrire "clip"+i._x (_x retourne l'abscisse du clip). Pour cela on utilisera la syntaxe suivante : clipConteneur["clip"+i]. En lisant cette ligne Flash travaillera sur un seul et unique clip (si i=5 alors il traduira cette ligne par clipConteneur.clip5).
Mais cette notation est lourde, pour simplifier l'écriture du code on va donc créer une variable raccourci :
Code : Autre
1
var chem2:MovieClip = chem1["clip"+i];

On peut aussi remplacer ces deux lignes par la ligne :
Code : Autre
1
var chem2:MovieClip = chem1.createEmptyMovieClip("clip"+i, var_profondeur);

C'était juste pour vous présenter une méthode pour récupérer un nom de variable.


On va maintenant créer plusieurs variables incluses dans chaque clip.
Les 2 premières sont les positions verticale et horizontale des clips quand ils seront au premier plan, on veut donc une valeur entre -largeur/2 et +largeur/2 (idem avec la variable 'hauteur').
Pourquoi ne pas prendre une valeur entre 0 et 'largeur' pour faire plus simple ?

C'est une simple question de représentation mentale, souvenez-vous on a défini un centre (avec les variables centre_x et centre_y) on calcule donc les coordonnées des clips en fonction de ce centre.
On doit aussi enregistrer la profondeur du clip (puisque l'on aura besoin de la récupérer pour la faire varier).
Enfin, la dernière nous sert juste à enregistrer la valeur actuelle de 'i' (elle nous sera utile pour récupérer les valeurs des variables du clip sur lequel on a cliqué).
Code : Autre
1
2
3
4
chem2.var_x = Math.round(Math.random()*largeur-largeur/2); 
chem2.var_y = Math.round(Math.random()*hauteur-hauteur/2); 
chem2.var_niv = var_profondeur; 
chem2.i = i;


Enfin on positionne le clip en fonction du centre et de ses coordonnées calculées plus haut.
Code : Autre
1
2
chem2._x = centre_x+chem2.var_x;
chem2._y = centre_y+chem2.var_y;


Maintenant que l'on a créé les variables et positionné le clip, il faut le remplir avec quelque chose (puisque voir se déplacer des clips vides, entre nous, c'est un peu difficile :D ).
On va donc y attacher le clip 'cercle' créé à l'étape 2, ainsi qu'un champ texte, dans lequel on va écrire la valeur de la ligne 'i' du tableau 'tab_nom' (qui je vous le rappelle contient des noms).
Code : Autre
1
2
3
4
chem2.attachMovie("cercle", "cercle", 1); 
chem2.createTextField("texte", 2, -10, -10, 20, 20); 
chem2.texte.text = tab_nom[i]; 
chem2.texte.selectable = false;

Note : La propriété 'selectable' nous indique si le champ texte est sélectionnable, par défaut elle est égale à 'True' (vrai en anglais) on la place donc sur 'False' (faux, en anglais aussi ^^ ).
Note 2 : La première ligne d'une liste se récupère via l'instruction monTableau[0], or justement cela tombe bien, notre boucle 'For' fait démarrer la variable 'i' à 0.


Bon les clips sont créés, mais il ont tous la même taille (logique ce sont des copies parfaites) et vous serez (j'espère) d'accords avec moi que pour donner un effet d'éloignement ce n'est pas le top ^^ .
On va donc arranger cela en modifiant les propriétés '_xscale' et '_yscale' des clips (elles modifient le % de la taille, par défaut elle sont à 100(%)).
Code : Autre
1
2
chem2._xscale = Math.ceil(chem2.var_niv/(profondeur/100)); 
chem2._yscale = Math.ceil(chem2.var_niv/(profondeur/100));

Note : 'chem2.var_niv' varie entre 0 et la valeur de la variable profondeur, il faut donc diviser cette valeur par profondeur/100 pour obtenir une valeur entre 0 et 100.


Maintenant il reste une étape à initialiser, c'est les actions à exécuter quand on clique sur le clip :
On déplace la tête de lecture de ce clip sur la deuxième image (le cercle à fond rouge dans notre cas).
Puis on supprime la temporisation que désigne la variable 'interval' pour éviter de créer 2 fois une même temporisation (ce qui aurait pour effet de doubler la fréquence d'exécution de la fonction temporisée).
Puis on recrée une temporisation de la fonction 'deplacement' toutes les 40 millisecondes à laquelle on envoie 3 paramètres ('chem1' pour l'adresse du clip conteneur; Le numéro d'index du clip sur lequel on a cliqué; et enfin la taille du tableau 'tab_nom', soit le nombre de clips).
Code : Autre
1
2
3
4
5
chem2.onRelease = function():Void{ 
    this.cercle.gotoAndStop(2); 
    clearInterval(interval); 
    interval = setInterval(deplacement,40,chem1,this.i,tab_nom.length); 
};



Récapitulatif de la fonction créée :
Secret (cliquez pour afficher)
Code : Autre
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function creer_btns(chem1:MovieClip, tab_nom:Array) {
    var taille:Number = tab_nom.length
    for (var i:Number=0 ; i<taille ; i++) {
        var var_profondeur:Number = Math.round(Math.random()*profondeur);
        var chem2:MovieClip = chem1.createEmptyMovieClip("clip"+i, var_profondeur);
        chem2.var_x = Math.round(Math.random()*largeur-largeur/2);
        chem2.var_y = Math.round(Math.random()*hauteur-hauteur/2);
        chem2.var_niv = var_profondeur;
        chem2.i = i;
        chem2._x = centre_x+chem2.var_x;
        chem2._y = centre_y+chem2.var_y;
        chem2.attachMovie("cercle", "cercle", 1);
        chem2.createTextField("texte", 2, -10, -10, 20, 20);
        chem2.texte.text = tab_nom[i];
        chem2.texte.selectable = false;
        chem2._xscale = Math.ceil(chem2.var_niv/(profondeur/100));
        chem2._yscale = Math.ceil(chem2.var_niv/(profondeur/100));
        chem2.onRelease = function():Void{
            this.cercle.gotoAndStop(2);
            clearInterval(interval);
            interval=setInterval(deplacement,40,chem1,this.i,tab_nom.length);
        };
    }
}


5) On crée une deuxième fonction prévue pour être exécutée en boucle pour simuler notre effet 3D : la fonction 'deplacement'.
On a vu dans la fonction 1 que l'on avait besoin d'envoyer 3 paramètres importants à la fonction 'deplacement', il faut donc créer des variables réceptrices.
Code : Autre
1
2
3
function deplacement(chem:MovieClip, var_i:Number, nbr:Number):Void {
    // instructions
}


La première étape consiste à récupérer le chemin pour accéder aux variables du clip sur lequel on a cliqué, pour cela aucun problème puisque l'on a pensé à envoyer la valeur de la variable 'i' du clip sur lequel on a cliqué.
Code : Autre
1
var chem1:MovieClip = chem["clip"+var_i];


À ce niveau une petite vérification s'impose, il faut regarder si le clip est arrivé au premier plan, c'est-à-dire que son niveau est maximal. Si c'est le cas on supprime la temporisation 'interval'.
Code : Autre
1
2
3
4
5
if (chem1.var_niv != profondeur) {
    // instruction
} else { 
    clearInterval(interval); 
}


Si le clip sur lequel on a cliqué n'est pas au premier plan alors il faut déplacer tous les clips, pour cela je vous propose de créer un effet de vitesse qui ralentit.
Je m'explique, on calcule la distance restante à parcourir, puis on demande au clip d'en parcourir la moitié.
À la prochaine exécution de la fonction on lui demande de faire pareil, mais comme la distance qu'il restera à parcourir a été divisée par 2 le clip avancera 2 fois moins vite, et ainsi de suite.
Si on applique cette méthode telle quelle, le clip n'arrivera jamais à destination, en effet il parcourra toujours la moitié de la distance restante, pour palier à ce petit problème de logique mathématique (qui peut donner mal à la tête :D ) on utilisera la méthode 'Math.ceil()' qui nous renvoie l'arrondi supérieur.
Le déplacement du clip se fera donc toujours d'un nombre entier, et quand la distance restante sera inférieure à 1 alors le clip arrivera à la position finale.

C'est ici qu'apparaît l'utilité de la variable 'frein', c'est elle qui va fixer le % de chemin restant à parcourir. (frein=2, la moitié; frein=3, le tiers, etc...)
Code : Autre
1
2
3
var vitesse:Number = Math.ceil((profondeur-chem1.var_niv)/frein); 
var vitesse_x:Number = Math.ceil(chem1.var_x/frein); 
var vitesse_y:Number = Math.ceil(chem1.var_y/frein);


Une fois les vitesses calculées, il faut modifier les variables et les propriétés des clips, on crée donc une boucle 'For' pour traiter tous les clips (le nombre de clips est contenu dans la variable 'nbr').
Code : Autre
1
2
3
for (var i:Number=0 ; i<nbr ; i++) {
    // instructions
}


On édite les variables des clips (on crée aussi un autre raccourci toujours pour simplifier l'écriture du code).
Code : Autre
1
2
3
4
var chem2:MovieClip = chem["clip"+i]; 
chem2.var_niv += vitesse; 
chem2.var_x -= vitesse_x; 
chem2.var_y -= vitesse_y;


Comme on augmente la valeur de la variable de niveau de tous les clips, il faut faire en sorte que les clips qui dépassent le premier plan soient remis en arrière-plan (on en profite aussi pour replacer la tête de lecture du clip 'cercle' sur l'image 1).
Code : Autre
1
2
3
4
if (chem2.var_niv>profondeur) { 
        chem2.cercle.gotoAndStop(1); 
        chem2.var_niv -= profondeur; 
}


Il ne nous reste plus qu'à déplacer les clips :
Modifier son niveau :
Code : Autre
1
chem2.swapDepths(chem2.var_niv);

Modifier sa taille :
Code : Autre
1
2
chem2._xscale=Math.ceil(chem2.var_niv/(profondeur/100)); 
chem2._yscale=Math.ceil(chem2.var_niv/(profondeur/100));

Note : on peut aussi écrire cette double instruction comme ceci :
chem2._xscale = chem2._yscale = Math.ceil(chem2.var_niv/(profondeur/100));
Ce qui va diviser son temps d'exécution par 2 (puisqu'avant on faisait faire à l'ordinateur 2 fois le même calcul.)


Enfin la dernière difficulté : pour donner l'impression que les clips viennent de loin (notion de fuyantes) on calcule le % du chemin parcouru et on le réutilise dans le positionnement des clips.
Code : Autre
1
2
3
var coef:Number = (chem2.var_niv/profondeur); 
chem2._x = centre_x+coef*chem2.var_x; 
chem2._y = centre_y+coef*chem2.var_y;


Récapitulatif de la deuxième fonction créée :
Secret (cliquez pour afficher)
Code : Autre
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function deplacement(chem:MovieClip, var_i:Number, nbr:Number):Void{
    var chem1:MovieClip = chem["clip"+var_i];
    if (chem1.var_niv != profondeur) {
        var vitesse:Number = Math.ceil((profondeur-chem1.var_niv)/frein);
        var vitesse_x:Number = Math.ceil(chem1.var_x/frein);
        var vitesse_y:Number = Math.ceil(chem1.var_y/frein);
        for (var i:Number=0 ; i<nbr ; i++) {
            var chem2:MovieClip = chem["clip"+i];
            chem2.var_niv += vitesse;
            chem2.var_x -= vitesse_x;
            chem2.var_y -= vitesse_y;
            if (chem2.var_niv>profondeur) {
                chem2.cercle.gotoAndStop(1);
                chem2.var_niv -= profondeur;
            }
            chem2.swapDepths(chem2.var_niv);
            chem2._xscale=Math.ceil(chem2.var_niv/(profondeur/100));
            chem2._yscale=Math.ceil(chem2.var_niv/(profondeur/100));
            var coef:Number = (chem2.var_niv/profondeur);
            chem2._x = centre_x+coef*chem2.var_x;
            chem2._y = centre_y+coef*chem2.var_y;
        }
    } else {
        clearInterval(interval);
    }
}


6) Maintenant il suffit d'exécuter la fonction 'creer_btns' pour lancer l'animation (et de lui passer les bons paramètres).
Code : Autre
1
creer_btns(_root, tab_nom_1);


7) Récapitulatif global (avec commentaires) :
Secret (cliquez pour afficher)
Code : Autre
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Création de la fonction 'creer_btns'.
function creer_btns(chem1:MovieClip, tab_nom:Array):Void{
    var taille:Number = tab_nom.length;
    for (var i:Number=0 ; i<taille ; i++) {
        var var_profondeur:Number = Math.round(Math.random()*profondeur);
        // Création du clip conteneur et du raccourci.
        var chem2:MovieClip = chem1.createEmptyMovieClip("clip"+i, var_profondeur);
        // Création des variables de sauvegarde.
        chem2.var_x = Math.round(Math.random()*largeur-largeur/2);
        chem2.var_y = Math.round(Math.random()*hauteur-hauteur/2);
        chem2.var_niv = var_profondeur;
        chem2.i = i;
        // Positionnement du clip.
        chem2._x = centre_x+chem2.var_x;
        chem2._y = centre_y+chem2.var_y;
        // On y attache le clip 'cercle'.
        chem2.attachMovie("cercle", "cercle", 1);
        // Création du champs texte.
        chem2.createTextField("texte", 2, -10, -10, 20, 20);
        // Écriture dans le champ texte.
        chem2.texte.text = tab_nom[i];
        // Rend le texte impossible à sélectionner.
        chem2.texte.selectable = false;
        // Redéfinit la taille du clip (en %).
        chem2._xscale = chem2._yscale = Math.ceil(chem2.var_niv/(profondeur/100));
        // Definit les actions à éxecuter lors du clic sur le clip.
        chem2.onRelease = function():Void{
            // On place la tête de lecture du clip 'cercle' sur l'image 2.
            this.cercle.gotoAndStop(2);
            // On supprime la temporisation 'interval' pour ne pas la déclencher 2 fois.
            clearInterval(interval);
            // On recrée la temporisation 'interval' qui exécutera la fonction 'deplacement', avec 3 paramètres, toutes les 40 millisecondes.
            interval = setInterval(deplacement, 40, chem1, this.i, tab_nom.length);
        };
    }
}
// Création de la fonction 'deplacement'.
function deplacement(chem:MovieClip, var_i:Number, nbr:Number):Void{
    // On crée un racourci.
    var chem1:MovieClip = chem["clip"+var_i];
    // On vérifie si le clip n'est pas déjà au premier plan.
    if (chem1.var_niv != profondeur) {
        // On calcule les vitesses de déplacement.
        // Note : La variable 'frein' diminue les vitesses et donc augmente le temps de déplacement des clips.
        var vitesse:Number = Math.ceil((profondeur-chem1.var_niv)/frein);
        var vitesse_x:Number = Math.ceil(chem1.var_x/frein);
        var vitesse_y:Number = Math.ceil(chem1.var_y/frein);
        // On édite les variables et les coordonnées de tous les clips.
        for (var i:Number=0 ; i<nbr ; i++) {
            // Création d'un raccourci.
            var chem2:MovieClip = chem["clip"+i];
            // On édite les variables.
            chem2.var_niv += vitesse;
            chem2.var_x -= vitesse_x;
            chem2.var_y -= vitesse_y;
            // Si le clip a dépassé le niveau de premier plan.
            if (chem2.var_niv>profondeur) {
                // On place la tête de lecture du clip 'cercle' sur l'image 1.
                chem2.cercle.gotoAndStop(1);
                // On édite la variable de niveau.
                chem2.var_niv -= profondeur;
            }
            // On édite le niveau du clip .
            chem2.swapDepths(chem2.var_niv);
            // On modifie la largeur et la hauteur du clip (en %).
            // Note : chem2.var_niv et profondeur, varient entre 0 et 1000, suite au petit calcul de valeur de sortie sont comprises entre 0 et 100.
            chem2._xscale = chem2._yscale=Math.ceil(chem2.var_niv/(profondeur/100));
            // On calcule le % du chemin parcouru.
            var coef:Number = (chem2.var_niv/profondeur);
            // On modifie les coordonnées du clip.
            chem2._x = centre_x+coef*chem2.var_x;
            chem2._y = centre_y+coef*chem2.var_y;
        }
    } else {
        // On supprime la temporisation 'interval' puisque le clip est arrivé au premier plan.
        clearInterval(interval);
    }
}
// Déclaration des variables globales.
var profondeur:Number = 1000;
var largeur:Number = 200;
var hauteur:Number = 200;
var centre_x:Number = 100;
var centre_y:Number = 100;
var frein:Number = 5;
var interval:Number;
// Création du tableau des noms.
var tab_nom_1:Array = new Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10");
// Exécution de la fonction 'creer_btns' à laquelle on envoie le chemin du clip conteneur (ici la scène principale '_root') et le tableau des noms.
creer_btns(_root, tab_nom_1);

Note : Les lignes précédées de '//' sont des commentaires, vous pouvez donc les supprimer sans aucun risque.


8) Et pour finir la dernière étape, celle que vous attendiez tous, l'ENREGISTREMENT de ce que vous avez fait tout au long de l'écriture du code bien évidement :) ... :euh: ... comment ça non ? :colere2: RHHAAA pas bien !

Conclusion :
Voilà il ne vous reste plus qu'à publier votre document.

Idées :

Ce tutoriel est une copie améliorée de celui que j'ai posté sur mon blog à l'adresse suivante : http://heero.blog.free.fr/index.php?article=6

Image utilisateur
Retour en haut Retour en haut


Créé : le 02/11/2007 à 23:23:43
Modifié : le 22/08/2008 à 16:07:56
Avancement : 100%
Licence : Copie non autorisée

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | RSS tutoriels | RSS news
Édité par Simple IT SARL : Nous contacter | Notre blog | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 156 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.1368s (0.1272s)