Kommunauty
Connexion
Inscription
« Étape 6 : Interrupteurs

Etape 7 : Création d'un éditeur

le 6 septembre 2011 • Flash • par Dawlin

Ici on va créer un éditeur de niveaux, pour permettre la possibilité de générer des maps très facilement, et que construire le jeu sans avoir besoin de programmer, une fois qu'il sera fini.

On crée donc un fichier Editeur.fla (qui est donc différent de notre jeu.fla)

Première chose, on commence par importer une map vide de 20*20 cases :


stop();
// #################### Création de la map vide
var myMap:Array = [[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
   [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]];

Vous remarquerez que j'ai quand même laissé des cases bloquantes sur les côtés, ça fait ça de moins à placer

Puis on va importer notre bibliothèque du jeu dans cet éditeur pour pouvoir utiliser les mêmes textures de sol (Vous faites juste un copié-collé de la bibliothèque

Ensuite, personnellement j'ai réglé la taille de l'éditeur comme ceci :

400*300

ça me permet d'avoir des cases de 15px de large (pour 30 en vrai, ici on aura une vision à l'échelle 1:2) et de garder 100px à côté pour placer des boutons qui me permettront de modifier la map.

Je place également une occurrence de mon clip vide "map", avec un nom d'occurrence "map"

Retour aux actions.

Je peux copier coller le code qui génère la map à partir de l'Array (oui, je peux le faire ) Cependant je vais le modifier un peu pour que la taille des textures soit divisée en deux.


// Ici on définit la largeur comme deux fois inférieure
larg = 15;

dessinerMap2 = function(){
for(i=0;i<myMap.length;i++){
for(j=0;j<myMap[i].length;j++){
// Si ce n'est pas un interrupteur
if(myMap[i][j]<20 || myMap[i][j]>30){
var clp:MovieClip = map.attachMovie(myMap[i][j],"t"+i+"-"+j,i*100+j);
clp._x = j*larg;
clp._y = i*larg;
}
else{
var clp:MovieClip = map.attachMovie("20","t"+i+"-"+j,map.getNextHighestDepth());
clp._x = j*larg;
clp._y = i*larg;
}
//On modifie également les tailles du clip
clp._width = larg;
clp._height = larg;
}
}
}
//Pourquoi 2 ? parce qu'on l'a un peu modifiée, alors il vaut mieux ne pas la mélanger à l'autre
dessinerMap2();

Ce qui nous donne :

Owiii c'est très joli !

Les boutons maintenant

J'ai placé tout à l'heure dans la barre à droite l'ensemble des textures (pour ce tutoriel, je n'en ait fait que 4 + un interrupteur). Ce sera en fait des boutons, qui nous permettra de cliquer dessus pour définir comment on veut modifier la case ... (Oui, j'explique mal ) En gros, je clique sur le bouton "pavé", puis sur une case de la map, et cette case se transformera en "pavé". En cliquant on modifiera également l'Array de la map.

Toutes ces textures ont chacune un numéro, et je vais leur donner leurs noms d'occurrence d'après ce numéro (0 pour pavé, 1 pour pierre, 2 pour bois...) avec juste avant la lettre "c", ce qui nous donnera des textures nommées c0, c1, c2 et c3 (l'interrupteur on verra après)

Puis, retour aux actions :


// Déclaration des boutons
/*
On crée une boucle qui va assigner à chaque bouton, numéro après numéro,
un comportement à adopter quand on clique dessus
*/
//NB : ici 4 est le nombre de textures
for(k=0;k<4;k++){
// On défini quel clip on veut modifier
var clp:MovieClip = _root["c"+k];
clp.k = k;
clp.onPress = function(){
// On assigne à la variable "modif" la valeur du numéro de la texture
modif = this.k;
}
}

Mais qu'est-ce que c'est que cette variable "modif" ??

Ne nous affolons pas Elle va nous servir à générer la map. Voyez-vous, quand on va cliquer sur la map, on va trouver grâce aux positions de la souris sur quelle case on vient de cliquer. Grâce à la variable "modif" on saura avec quelle case on veut la remplacer (puisque la variable modif prendra le numéro de la texture qu'on vient de sélectionner dans la barre de droite). On pourra alors modifier la case voulue.

(au préalable, tout en haut du code, on initialise la variable "modif" à 0 avec "modif = 0;")

Écrivons donc ce code !


// Déclaration de la réaction de la map :
map.onPress = function(){
caseX = Math.floor(_xmouse/larg);
caseY = Math.floor(_ymouse/larg);
// Puis on modifie la map :
myMap[caseY][caseX] = modif;
dessinerMap2();
}

C'est très très vite vu, de faire un éditeur, puisqu'on a déjà tout fait dans la programmation du jeu !

Allez, un petit test de ce que ça donne :

Ce qui me permet de faire taire les mauvaises langues tout de suite : Non, il n'y a pas de latence de folie (N'est-ce pas, Mizur ? )

L'interrupteur

Ou plutôt devrais-je dire les interrupteurs. Nous avons plusieurs problèmes dus à ces interrupteurs :

  • Ils ont tous la même texture (n°20) mais pas le même numéro (de 20 à 30)
  • Ils sont de plusieurs types
  • Ils ont besoin de paramètres (la case à remplacer, et en quoi la remplacer)

Je rappelle que dans ce tutoriel, on ne s'occuppe que des interrupteurs qui modifient des cases, donc en gros ouvrent des portes (à vous de coder les interrupteurs qui spawnent des monstres, qui font gagner, mourrir, ...) donc pour le problème des types, c'est réglé.

Pour les autres maintenant, je vous propose de commencer par le n°3.

Donc, quand on cliquera sur un interrupteur, ça ne modifiera pas directement la variable "modif", mais fera apparaître un cadre qui permettra de modifier les différents paramètres.

On commence par créer un clip d'occurrence "interParam" qui contiendra :

  • Un champ de texte de saisie d'occurrence "rX" (pour "case à remplacer en X")
  • Un champ de texte de saisie d'occurrence "rY" (pour "case à remplacer en Y")
  • Un champ de texte de saisie d'occurrence "rt" (pour "texture de remplacement")
  • Un bouton pour valider d'occurrence "btnV"

Et ça ressemble à ça :

Vous remarquerez que pour me simplifier la vie quand je rentrerai le numéro de la texture dans le champ rt j'ai mis un champ de texte qui me donne le numéro des textures

Maintenant on va pouvoir écrire le code de l'interrupteur :


// Gestion du bouton pour générer des interrupteurs
//On commence par effacer interParam qui ne sert à rien pour l'instant
interParam._visible = false;
//puis on définit le numéro de l'interrupteur (on commence à 20)
nint = 20;
var interruptArray:Array = new Array();
//et enfin on commence le code
c20.onPress = function(){
//on commence par définir modif à 0 pour éviter qu'on place n'importe quoi
modif = 0;

interParam._visible = true;

//Et on regarde si on clique sur le bouton valider :
interParam.btnV.onPress = function(){
//On récolte les informations
var nCaseX:Number = parseInt(interParam.rX.text);
var nCaseY:Number = parseInt(interParam.rY.text);
var nTexture:Number = parseInt(interParam.rt.text);
if(nCaseX && nCaseY && nTexture){
//Puis on inscrit ces informations dans interruptArray, la grosse array qui contient les paramètres interrupteurs
interruptArray[nint] = [0,nCaseX,nCaseY,nTexture];
//Puis on définit modif parce qu'on peut maintenant placer le carré :
modif = nint;
// On incrémente nint pour que le prochain interrupteur n'ait pas ce numéro :
nint++;
//Et on ferme la fenêtre de paramètres
interParam._visible = false;
}
}
}

Mais avec ce code-ci, on pourra placer 50 fois le même interrupteur tant qu'on ne clique pas sur une autre texture ! Fichtre !

Voici le nouveau code de quand on clique sur la map, qui tient compte de ce détail :


// Déclaration de la réaction de la map :
map.onPress = function(){
caseX = Math.floor(_xmouse/larg);
caseY = Math.floor(_ymouse/larg);
// Puis on modifie la map :
myMap[caseY][caseX] = modif;
dessinerMap2();

//Si il s'agit d'un interrupteur :
if(modif >=20 && modif<=30){
modif = 0;
}
}

Et ... :

Export

Bon... Maintenant qu'on est capable de générer une map avec ça, il faut pouvoir l'exporter !

On rajoute un bouton pour exporter la map, n'importe où, avec une occurrence "valider"

Ce bouton va donc gérer la conversion de tout ça en XML. eh oui ! Car il est temps de passer à un format plus souple : le XML.


//Code de bouton pour exporter :
valider.onPress=function(){
//Première chose : placer le début du XML :
mapXML = "<root>\n<map>\n";
//ensuite, lecture de la map (oui c'est le même principe que pour la dessiner)
for(i=0;i<myMap.length;i++){
mapXML+=" <ligne>\n";
for(j=0;j<myMap[i].length;j++){
mapXML+=" <case>"+myMap[i][j]+"</case>\n";
}
mapXML+=" </ligne>\n";
}
mapXML+="</map>\n";

/*Il a donc lu la map et l'a convertie en XML... Reste une info...
interruptArray ! Comment voulez-vous que nos interrupteurs fonctionnent
sans leurs paramètres !!
Heureusement le XML peut accueillir toutes les informations
dont nous avons besoin...*/
mapXML+="<interrupteurs>\n";
for(m=20;m<interruptArray.length;m++){
mapXML+=" <inter>\n";
mapXML+=" <numero>"+m+"</numero>\n";
mapXML+=" <type>"+interruptArray[m][0]+"</type>\n";
mapXML+=" <rX>"+interruptArray[m][1]+"</rX>\n";
mapXML+=" <rY>"+interruptArray[m][2]+"</rY>\n";
mapXML+=" <rt>"+interruptArray[m][3]+"</rt>\n";
mapXML+=" </inter>\n";
}
//On ferme le XML
mapXML+="</interrupteurs>\n</root>";
//trace(mapXML);

//Et on va à l'image  suivante
nextFrame();
}

On va à l'image suivante ... Ah oui ! Ben créez-la !

Les méchants

Cette nouvelle image, on ne va y définir que le nombre de méchants qu'on veut. On pourrait mettre un champ de texte où on rentre ce qu'on veut, ou une liste déroulante, mais on va plutôt mettre un champ de texte qui affiche le nombre de méchants, et des boutons + et -. Ainsi qu'un bouton valider.

  • Le texte a pour occurrence "chTexte"
  • Le bouton + a pour occurrence "bPlus"
  • Le bouton - a pour occurrence "bMoins"
  • Le bouton Valider a pour occurrence "valider"

Ah oui, c'est moche, mais moi d'un autre côté je vous apprends à programmer, pas à designer, alors le graphisme, j'y vais un peu vite

Codons !


stop();
//Code de calcul des méchants
//On initialise
nMechants = 0;
//On actualise le champ de texte
chTexte.text = nMechants;

bPlus.onPress = function(){
nMechants++;
//On actualise le champ de texte
chTexte.text = nMechants;
}

bMoins.onPress = function(){
nMechants--;
//On actualise le champ de texte
chTexte.text = nMechants;
}

valider.onPress = function(){

nextFrame();
}

Attention, il n'y a pas de limite ! Si Vous voulez faire un niveau avec 750 monstres, allez-y !

Ce code va vous emmener à la dernière image, celle que vous créez maintenant

Enfin, la dernière image. Sur cette image il n'y a qu'un énorme champ de texte écrit en très petit où va s'afficher la variable "mapXML". Donc son occurrence est "mapTxt" et dans les actions j'écris :


stop();
mapTxt.text = mapXML;

Puisque Flash n'est pas très fort pour enregistrer les fichiers tout seul, vous devrez copier-coller ce texte dans un fichier que vous allez appeller "map.xml" et que vous allez placer juste à côté de votre jeu.

Dans la prochaine étape on verra comment lire ce XML, en modifiant notre code déjà écrit dans les fichiers .as que nous avions faits.

L'éditeur est donc fini, si vous avez un petit problème n'hésitez pas à poser des questions, et/ou à télécharger la source

En attendant, rendez-vous à la prochaine étape !

Étape 8 : Récupérer les informations XML »


  
Aucun commentaire

Sois le premier à débuter une discussion à propos de cet article !



Ajoute un commentaire !

Ajouter une image... Trouvée sur internet » De mon PC »
Adresse URL :
Adresse de la page de la vidéo :
Taille du texte :
Couleur du texte :

Article lu 1785 fois.