Forums Développement Multimédia

Aller au contenu

[AS3] Créer une interface pour chaque case ?

map isométrique CODE

25 réponses à ce sujet

#1 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 01 January 2013 - 19:23 PM

Bonjour à tous & bonne année,

Alors j'ai commencé un jeu avec une map isométrique et je voudrais savoir comment faire pour que lorsqu'on appuie sur une case de la map il y est une "interface" avec des informations sur la case mais aussi des boutons qui permettent des actions comme par exemple un bouton changer. Cette interface doit aussi posséder un bouton fermer en haut à droite.
Je voudrais donc savoir ce que je dois mettre dans ma fonction "clicked" et qu'est-ce que je dois dessiner ( toute la fenêtre ou juste des parties ).

De plus je souhaite savoir comment faire pour sélectionner plusieurs cases en même temps ( drag & drop ) et aussi du coup créer une interface avec plusieurs cases avec lorsqu'elles existes les valeurs et actions communes à toutes les cases sélectionnées.

Mais c'est pas la peine de vous casser la tête avec du code, je veux surtout des conseils, idées, ... Merci d'avance.

Flivasso.

#2 draad

  • Members
  • PipPipPipPipPipPipPipPip
  • 654 messages

Posté 01 January 2013 - 21:03 PM

Coucou,

Citation

Je voudrais donc savoir ce que je dois mettre dans ma fonction "clicked" et qu'est-ce que je dois dessiner ( toute la fenêtre ou juste des parties ).

Je pense que le mieux dans ce cas, c'est de te créer un classe 'Tile_Tooltip' qui sera ta fenêtre d'information/gui. Sur un évènement clic, tu crée une instance de ta classe 'Tile_Tooltip' et tu viens la placer a la position X-Y de la tuile de terrain qui fait l'objet du clic, avec une suppression de la popup sur un MOUSE_OUT par exemple.

Pour ta sélection multiple, peut-être utiliser une détection de la durée du clic. Si le clic dure plus longtemps que 2 secondes, tu passe une variable Moose_SelectMode:Boolean = true. Sur tes tuiles, tu rajoute un évènement au survol : Si Moose_SelectMode est égal a true, alors ma tuile change de couleur et je l'ajoute dans un tableau qui garde en mémoire toutes les tuiles sélectionnées.

J'espère t'avoir donné des pistes, bon courage :)

#3 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 01 January 2013 - 23:04 PM

Salut,
Merci pour ta réponse alors déjà je pense avoir compris pour la fenêtre d'interface ( je vais voir ça demain pour voir si j'y arrive ). Par contre pour les actions soit j'ai pas tout compris soit et bien c'est l'inverse ( :P ), en fait donc je veux que au final lorsque l'on clique d'une case à une autre case toutes les cases comprises entre le rectangle formé soit sélectionnées ( un peu comme quand on sélectionne plusieurs fichiers du bureau windows ) et que du coup au lieu d'avoir une fenêtre d'interface normal il ne reste dans l'interface que les informations ( variables ) et actions possibles ( comme par exemple un bouton transformer ces tiles ou planter quelque chose dessus ) qui sont exactements les même pour toutes les cases sélectionnées. Pour l'instant j'ai mis un Timer sur la classe map, deux écouteurs dans la classe Tile ( MOUSE DOWN et UP ) et donc le DOWN transforme une variable en "start" et le UP en "end" ensuite j'analyse ça sur le Timer ( donc chaque seconde pour l'instant ).
Il y sûrement plus simple et surtout plus confortable pour le "joueur" mais je ne vois pas comment je pourrais faire sans rendre mon code inutilisable après.

Flivasso.

#4 draad

  • Members
  • PipPipPipPipPipPipPipPip
  • 654 messages

Posté 01 January 2013 - 23:51 PM

Coucou,

Tu pourrais te baser sur un tableau. Par exemple :

monArrayDeCasesSelectionnees : Array = [];

Lorsque le joueur selectionne une ou plusieures cases, tu ajoute ses cases dans ce tableau, lorsqu'il les deselectionnes tu vide le tableau. Puis tu affiche ta popup en fonction.



Si monArrayDeCasesSelectionnees.length == 1, alors ma popup affiche ceci
Si monArrayDeCasesSelectionnees.length > 1, alors ma popup affiche cela
 


#5 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 01:22 AM

Resalut,

Ah oui c'est bon merci et au lieu de faire un Timer ( enfin je l'utiliserait pour autre chose ) la vérification se fera lorsque la map enregistrera un MOUSE UP. Sinon t'aurais pas une solution pour lorsqu'on a un écouteur de clic sur la classe map savoir qu'elle est la tile en particulier qui a été cliquer ? Ça arrangerait tout finalement parce que ( je sais pas si c'est clair mais bon :P ) je n'aurais pas à remonter de la classe Tile ( ou il y a les écouteurs ) vers la classe Map ( ou il y a toutes les tiles ) via des variables publiques et des vérifications ( donc mon Timer et la double boucle qui parcourt l'Array mapChild qui contient toutes les tiles de la map ).
Donc là je dort et demain si je peut je corrige déjà ce que j'arrive et je poste des bouts de code. Au passage c'est quoi les inconvénients / désavantages de créer un jeu multi joueur qui se base sur un fichier XML partagé ( ou donc chaque joueur peut modifier ce fichier qui est la map ) ?

Encore merci :P.
Flivasso.

#6 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 12:00 PM

Re,

Voici le début de ma classe ToolTip :

package
{
import flash.display.Sprite;

public class ToolTip extends Sprite
{
  public var toolArray:Array = new Array();
  public function ToolTip(tTArray:Array)
  {
   toolArray = tTArray;
   if ( toolArray.length == 0 )
   {
        // probleme ?
   } else if ( toolArray.length == 1 )
   {
        // On affiche pour une seule case sélectionnée.
   } else
   {
        // On affiche pour plusieurs cases ( en filtrant les 'choses' non communes à toutes les cases.
   }
  }
}

}
 

J'hésite entre créer un ToolTip que je modifie mais qui reste le même ( et donc il est visible si au moins une case est sélectionnée ) ou à chaque fois qu'on sélectionne supprimer l'ancien ToolTip et en recréer un autre.

Flivasso.

#7 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 12:10 PM

Désolé de devoir poster à la suite,

j'ai trouvé pour la lecture direct en fonction du clique il suffit d'utiliser :

trace(evt.target);
 

Du coup si j'ai bien compris pour chaque écouteur je dois retourner la position X et Y de la tile cliqué dans mon tableau et grâce a une boucle ajouter aussi tout ceux qui sont entre ( pour former un rectangle ). Le seul hic c'est que le joueur doit pouvoir le faire à l'envers aussi ( donc si il sélectionne le bas de la map vers le haut çà doit aussi marcher et donner exactement le même résultat ). Reste plus qu'à coder tout çà proprement.

Flivasso.

#8 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 02 January 2013 - 12:12 PM

Bonjour Flivasso.

Citation

J'hésite entre créer un ToolTip que je modifie mais qui reste le même ( et donc il est visible si au moins une case est sélectionnée ) ou à chaque fois qu'on sélectionne supprimer l'ancien ToolTip et en recréer un autre.

Ça dépend de la complexité et de l'optimisation des perfs que tu souhaites, plus que d'un choix théorique, amha…

Au compromis, je décomposerais le ToolTip en 2 : les infos permanentes qu'il n'y a jamais besoin de redessiner (typiquement, le fond, les titres ?) + les infos particulières.
Du coup, un seul ToolTip, qui affiche un miniTip spécifique à la tuile. MiniTip que je créerais à la volée s'il n'existe pas, et que je masquerais ensuite sans le détruire pour le reexploiter si besoin…


Pour ta question sur les tuiles multiple…
Là, je me poserais calmement et je me demanderais si le principe de base Ça n'est pas celui-ci :
- afficher les infos communes aux tuiles d'un ensemble de tuiles (tableau ? vecteur ?)
Avec ce principe le même développement affichera toutes les infos s'il n'y a qu'une tuile et les infos communes s'il y en a plusieurs.
Par contre, Ça demande une gestion pointue des infos pour qu'elles soient "listables" proprement (mais Ça, tu devras de toute faÇon le faire …)

#9 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 02 January 2013 - 12:20 PM

Citation

Le seul hic c'est que le joueur doit pouvoir le faire à l'envers aussi ( donc si il sélectionne le bas de la map vers le haut çà doit aussi marcher et donner exactement le même résultat ). Reste plus qu'à coder tout çà proprement.
Alors, un principe simple :
- au mouseDown, je mémorise la tuile cliquée comme étant le coin1
- au mouseUp, je mémorise la tuile cliquée comme étant le coin2

Après, il y a plusieurs solutions pour construire la sélection.
En voici une :
- - je crée un coin supérieur dont les coordonnées sont le plus petit x et y de point1 et point2
- - je crée un coin inférieur dont les coordonnées sont le plus grand x et y de point1 et point2
- - je récupère les tuiles entre coin supérieur et coin inférieur (dans un tableau ? un vecteur ?)

A noter que cet algo fonctionne aussi pour une sélection d'une seule tuile :-)

#10 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 12:29 PM

J'avais effectivement pas penser à prendre les coordonnées supérieurs et inférieurs, merci, j'voulais passer à l'étape trois directement. Du coup c'est plus simple surtout que j'ai ajouter les variables eX et eY à mes Tiles. Mais je comprend pas pourquoi evt.target.eX et evt.target.eY revoie toujours undefined. Pourquoi y a une valeur par défaut ( 0 ) et en dehors de cela la valeur par défaut fonctionne correctement ( les variables sont bien publiques :P ).

Flivasso.

#11 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 02 January 2013 - 12:33 PM

Vérifie que le type de l'objet target est bien Tile…
Target te renvoie l'objet cliqué de plus bas niveau.
Donc, ça peut aussi être un enfant de ta tuile (fond… ?)
ça expliquerais que tu ne retrouves pas les propriétés que tu attends.

Une des solutions : appliquer un mouseChildren==false à la création de ta tuile.
Comme ça, les enfants ne devraient plus t'embêter.

#12 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 12:39 PM

Ah oui c'est exactement çà, j'avais le MovieClip au lieu de la Tile ( mais comme mes MovieClips s'appellent Tile0, Tile1, ... j'avais pas fait gaffe xD ). Encore merci t'es vraiment super sympa !

Flivasso.

#13 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 13:15 PM

Voici donc la solution que j'ai trouvé, finalement j'ai choisis l'option avec chaque classe map a un seul toolTip que l'on peut afficher / enlever et lorsqu'on veux l'afficher il faut préciser les tiles dans un tableau en paramètre ( pour qu'il est toutes les informations utiles ).
Ensuite voici ce qu'il y a dans ma classe Map, j'ai pas encore vérifier mais çà m'a l'air correct :

function clikmu ( emu:MouseEvent )
  {
   if ( emu.target )
   {
        selectUp = [emu.target.eY, emu.target.eY];
   }
   if ( selectUp == selectDown )
   {
        // toolTip target.
   } else
   {
        selectDown, selectUp = reorganize(selectDown, selectUp);
        // toolTip des nouveaux coins.
   }
  }

  function reorganize(arr1, arr2)
  {
   if ( arr1[0] > arr2[0] )
   {
        var prep0 = arr1[0];
        arr1[0] = arr2[0];
        arr2[0] = prep0;
   }
   if ( arr1[1] > arr2[1] )
   {
        var prep1 = arr1[1];
        arr1[1] = arr2[1];
        arr2[1] = prep1;
   }
   return arr1, arr2;
  }
 

Flivasso.

#14 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 13:41 PM

Est-ce que vous connaissez un "problème" flash qui fasse que plus rien ne répond ( trace, addChild ) sans qu'il n'y est d'erreur ni en output ni dans la fenêtre des erreurs ? C'est vraiment très bizarre j'y comprend plus rien. J'ai essayé pour voir si c'était pas un déréglage mais non, pour le faire j'ai enlever la classe principale ( main ) dans les propriétés du .fla et mis un trace brut et çà a marché. Autrement rien ne fonctionne.

Flivasso.

#15 draad

  • Members
  • PipPipPipPipPipPipPipPip
  • 654 messages

Posté 02 January 2013 - 13:50 PM

Coucou,

Parfois, le builder reste bloqué chez moi, c'est du a un arrêt incomplété d'un debug en général, et ca empeche tout nouveau build d'etre construit.

Pour corriger le problème, la seule solution que j'ai trouvé c'est de redémarrer Flash Builder.

Mais ton probleme ne vient peut-etre pas de là, difficile a dire sans être en présence du code. Essaie de remonter la piste et de supprimer tes dernieres modifications au code jusqu'a la derniere version fonctionnelle.

#16 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 13:59 PM

Ah non c'était vraiment con ( un public var ttposx = ttposy = 0; et un stage.mouseChildren au lieu de this.mouseChildren ) mais je savais pas que çà pouvait tout bloquer comme çà.

Flivasso.

#17 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 14:25 PM

Alors pour revenir au sujet principale,

maintenant lorsque l'on sélectionne une seule case ( selectUp == selectDown ) les éléments par défaut du ToolTip s'affiche et passe derrière la map. Donc j'ai deux questions : comment on fait pour savoir si le target est une "instance" de classe Tile ? Et aussi y a t-il un moyen de mettre le ToolTip toujours devant ou sinon il faut faire en sorte de le remettre devant ( ce qui implique plus de variable et plus de lenteur ).

Flivasso.

#18 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 02 January 2013 - 14:48 PM

Pour le typage :
if (a is Tuile) {

}

Pour la liste d'affichage :
- une solution propre :
- - avoir des conteneurs dédiés, et tu gères l'ordre d'affichage de ces conteneurs. Ensuite, tu affiches le ToolTip sur le conteneur du dessus, la carte sur le conteneur du dessous (pour faire simple).
- une solution moins propre :
- - refaire un addChild(toolTip) du ToolTip à chaque fois, ou un addChildAt(toolTip, numChildren-1)

#19 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 15:47 PM

Merci beaucoup c'est juste parfait !

#20 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 18:29 PM

Re,

Alors on est d'accord c'est vraiment très très moche mais au moins çà donne une idée de ce que je souhaite faire ( enfin à peu près quoi ) donc voici le lien de ma réalisation ( .swf ) ici. Je souhaite pour terminer cette partie ( l'interface case par case ) faire en sorte que lorsque mon interface est affiché le reste du jeu soit grisaillé et surtout inutilisable ( et çà même en dehors du "visible", c'est à dire même lorsqu'on passe en plein écran ). Je commence donc l'algorithme que j'avais laissé de côté pour faire le carré de sélection.

Flivasso.

#21 draad

  • Members
  • PipPipPipPipPipPipPipPip
  • 654 messages

Posté 02 January 2013 - 18:42 PM

Coucou,

Content que tu t'en sorte :)

Pour griser et rendre inaccessible le reste du jeu lorsque ta popup est affichee, tu peux tout simplement rajouter un grand filtre noir en arriere plan de ta popup, avec son alpha diminue a 75%. Cela fera l'effet grise, et l'ecran captera les evenements de clic a la place de ton terrain/gui.

#22 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 02 January 2013 - 18:48 PM

Moi, je ferais l'inverse :) mais ça n'est pas fondamentalement différent…

Si tu as suivi la solution "propre" tu as un conteneur générique pour le jeu.
Tu as donc juste à appliquer un alpha a ce conteneur et lui appliquer un mouseEnabled=mouseChildren=false;
Pour le rendre à nouveau actif, alpha==1 et mouseEnabled=mouseChildren=true;

Et si tu veux un effet sombre, tu joues avec la couleur de fond de ta scène.

#23 draad

  • Members
  • PipPipPipPipPipPipPipPip
  • 654 messages

Posté 02 January 2013 - 19:12 PM

Je comprends ton point dldler, je faisait comme tu le conseille aussi avant. Mais au final je trouve ca plus pratique d'ajouter le filtre directement a mes popups, cela permet entre autre de pouvoir cumuler les popup les une sur les autres en etant assure que seule la derniere popup affichee puisse recevoir des interactions.

#24 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 19:37 PM

Un alpha au container qui contient mes tiles donc, mais il est déjà au max normalement non ( 100% ? ) et en plus seul les tiles risquent de noircir du coup çà donne pas l'effet attendu, enfin je crois.
Vous savez comment faire pour que lorsque la souris passe sur un TextField elle fasse comme si il était pas là et pire qu'elle passe à "l'objet derrière" qui est mon bouton ?
Flivasso.

#25 draad

  • Members
  • PipPipPipPipPipPipPipPip
  • 654 messages

Posté 02 January 2013 - 19:48 PM

Non Flivasso,

Tu devrais avoir plusieurs layers dans ton application.

Un layer pour ton terrain -> la tu affiche toutes tes uiles
Un layer pour ton gui -> la tu affiche le gui
Un layer pour le masque -> la tu affiche un ecran noir a 75% alpha
puis tout en haut, le layer des popup.

#26 Flivasso

    Ceinture Jaune

  • Members
  • PipPip
  • 17 messages

Posté 02 January 2013 - 20:21 PM

"Un layer pour ton gui" ? Je vois pas trop ce que tu entends par là. Mais pour la layer popup et le masque j'ai qu'un seul popup de toutes manières et au pire j'ajouterais d'autres masques dans les autres popups car dans tout les cas je n'aurait jamais besoin de mettre deux popups en même temps puisqu'ils sont "bloquants". D'ailleurs je vais ajouter un petit drag&drop au popup.

Flivasso.



1 utilisateur(s) li(sen)t ce sujet

0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)