Forums Développement Multimédia

Aller au contenu

Drag & Drop ✔

CODE Actionscript

43 réponses à ce sujet

#1 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 15 November 2012 - 19:05 PM

Bonjour à tous,

Je souhaiterais réaliser un drag & drop similaire (en as3) au fichier ci-joint mais j'imagine ne pas avoir le niveau pour le reproduire étant la complexité de celui-ci, j'ai appris à réaliser un drag & drop de base mais pour la suite c'est chaud les marrons chaud ! toutes l'aide ou tuto que vous pourrez m'apporter est la bienvenue.
Merci à vous ;-) !

Fichier(s) joint(s)



#2 Nataly

    Community Jane

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 5783 messages

Posté 15 November 2012 - 19:20 PM

A priori, pas si dur ;)

au clic (enfonce), mémoriser le conteneur
au lache, choper l'enfant du conteneur superposé (parcourir à coup de hitTest) l'ajouter au conteneur mémorisé et ajouter le clip courant au clip survolé…

Je m'y essaie et l'ajoute au tuto concerné juste frais (insensé : alors que je séchais sur les exo simples de mise en œuvre, hop ! il en tombe de partout :roi: ).
Le savoir est le seul bien qui s'accroit quand on le partage
une tartine de tutos

#3 Nataly

    Community Jane

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 5783 messages

Posté 15 November 2012 - 20:50 PM

bon, après une pause tel/mandarines, il y a bien plus simple ;)

parti pris : on se complique pas, comprendre j'écris pas plein du code pour ajouter des trucs et des machins, tout est sur la scène Et j'en rame un minimum ds l'ide, moins je nomme, mieux je me porte :P



- Afficher le SWF -
Fichier joint  intervertit.swf   1.56 Ko   6 téléchargement(s)

l'idée, c'est :
• les clips ds un conteneur,
• on écoute le 'enfonce' en baladant le clip renvoyé par 'target' (on note au passage ses coordonnées d'origine)
• on écoute l'événement UP (qdLache) sur la scène en phase capture
--> balayer le tableau des clips et tester collision
si collision on interverti les coordonnées des deux clips et on sort
sinon on renvoi le clip en cours à ses coord d'origine.

voilà, et tu mets autant de clip que tu veux ds le conteneur ! ça me plait super comme exo ! \0/
:Hola:

//un tableau des enfants du clip 'contenant'
var _tbFormes:Array=new Array();
var _max:int=contenant.numChildren;
for (var i:int=0; i<_max; i++) {
        _tbFormes.push(contenant.getChildAt(i));
}

contenant.addEventListener(MouseEvent.MOUSE_DOWN,qdEnfonce);
stage.addEventListener(MouseEvent.MOUSE_UP, qdLache,true);

function qdLache(me:MouseEvent) {
    stopDrag();
        for (var i:int=0; i<_max; i++) {
                if (_tbFormes[i]!=me.target && _tbFormes[i].hitTestObject(me.target)) {
                        //trace("placer courant aux coord de _tbFormes[i]");
                        me.target.x=_tbFormes[i].x;
                        me.target.y=_tbFormes[i].y;
                        //trace("placer _tbFormes[i] aux coord de courant ");
                        _tbFormes[i].x=me.target.xDep;
                        _tbFormes[i].y=me.target.yDep;
                        return;// c'est bon on sort
                }
        }
   // trace("pas de superposition");
        me.target.x=me.target.xDep;
        me.target.y=me.target.yDep;
}

function qdEnfonce(me:MouseEvent) {
        contenant.addChild(MovieClip(me.target));
        me.target.startDrag();
        me.target.xDep=me.target.x;
        me.target.yDep=me.target.y;
}




sources CS3

Fichier(s) joint(s)


Le savoir est le seul bien qui s'accroit quand on le partage
une tartine de tutos

#4 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 15 November 2012 - 20:59 PM

En tout cas, gros merci Nataly pour ton super travail sur ce fameux tutorial ;) !

#5 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 15 November 2012 - 21:16 PM

Vraiment excellent Nataly, :Hola: , je vais le décortiquer pour l'assimiler et bosser dessus.

#6 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 15 November 2012 - 22:33 PM

Yop,

Juste pour mettre mon grain de sel, personnellement je serai parti sur une grille.
Je me trompe peut être totalement mais ça me semble plus simple à gérer.
Une grille et un tableau, en fonction de la case où se trouve la souris quand je drop j’intervertis les deux index (la case vide et celle où je viens de lâcher l'objet). Pour l'affichage je replace les clips par le numéro de la case où il est * sa taille (on module si on veux faire plusieurs lignes).

#7 Nataly

    Community Jane

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 5783 messages

Posté 15 November 2012 - 23:22 PM

j'avais pas vu (dans l'enthousiasme :P ) qu'il y avait une combinaison à trouver.

J'ai pas voulu lâcher le parti pris du j'en rame un minimum et apporté une solution qui vaut ce qu'elle vaut pour ce que c'est faire ;)

le tout est développé commenté dans le tuto avé les sources.

Voir le messageMonsieur Spi, le 15 November 2012 - 22:33 PM, dit :

ça me semble plus simple à gérer.

ça c'est à voir (gnk gnk)

différent et intéressant en revanche c'est sûr… n'hésite pas, si ça te dit d'enrichir le tuto de ta vison des choses \o/
Le savoir est le seul bien qui s'accroit quand on le partage
une tartine de tutos

#8 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 16 November 2012 - 07:36 AM

Salut Nataly,

Je suis heureux que mon post t'es enthousiasmée, j'aurais apporté au moins et pour une fois un minimun de contribution au forum :D !

Sur le mélange des formes, l'option automatique et aléatoire est pas mal mais je pensais plus à décider et d'ordonner le mélange des clips à ma guise.

Merci encore pour cette contribution !

Bonne journée ;) !

#9 Nataly

    Community Jane

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 5783 messages

Posté 16 November 2012 - 09:37 AM

Voir le messagecortoh, le 16 November 2012 - 07:36 AM, dit :

je pensais plus à décider et d'ordonner le mélange des clips à ma guise.

Ça je te fais confiance, c'est pas le plus dur : nommer les clip, se palucher un x et un y pour chacun, tu sauras ;)

bon wik et à bientôt :)
Le savoir est le seul bien qui s'accroit quand on le partage
une tartine de tutos

#10 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 16 November 2012 - 10:45 AM

Re,

Pour le fun (c'est un peu crade comme code), moi j'ai ça :

import flash.display.MovieClip;
import flash.desktop.Clipboard;
import flash.events.MouseEvent;

var c1:MovieClip = new C1();
var c2:MovieClip = new C2();
var c3:MovieClip = new C3();
var c4:MovieClip = new C4();

var tab:Array = [c1,c2,c3,c4];
var T:int = tab.length;
var L:int = c1.width;
var enCours:MovieClip;

for (var i:int=0; i<T;i++){
        var ob:MovieClip = tab[i];
        ob.addEventListener(MouseEvent.MOUSE_DOWN, attrape);
        ob.addEventListener(MouseEvent.MOUSE_UP, lache);
        ob.buttonMode=true;
        addChild(ob);
}
replace();

function attrape(e:MouseEvent):void{
        enCours = MovieClip(e.target);
        enCours.startDrag();
        setChildIndex(enCours,T-1);
}

function lache(e:MouseEvent):void{
        var M:int = mouseX/L;
        if(M<T){
                tab[tab.indexOf(enCours)] = tab[M];
                tab[M] = enCours;
                stopDrag();
                replace();
        }
}

function replace():void{
        for (var i:int=0; i<T;i++){
                tab[i].x = i*L;
                tab[i].y = 0;
        }
}
 

Il y a surement plus court mais le matin j'ai du mal...
Techniquement, j'utilise juste un tableau et la position de la souris par rapport aux cases du tableau.
Quand je cliques j'enregistre l'objet cliqué dans une variable temporaire.
Quand je relâche je regarde la position de la souris dans le tableau pour retrouver l'index de la case.
Puis j'intervertis les index du tableau (case vide et case ou j'ai relâché).
Et je me sert d'une fonction annexe pour replacer tous les clips du tableau en fonction de leur index.

Je trouve ça plus simple car je ne stocke pas tout un tas de positions temporaires, tout se fait par l'intermédiaire du tableau et tout ce que j'ai à stocker c'est le clip en lui même, pas de tests de collisions, rien qui joue avec les clips (à part pour les replacer), que de l'interprétation entre la position de la souris et les cases du tableau. Le code concerné tient en deux lignes (inversion des index), le reste c'est du blabla qui concerne l'affichage etc... ;-)

Pour savoir si la combinaison est bonne il suffit de vérifier le tableau une fois les clips replacés (ou au moment où on lâche l'objet, peu importe).

Pour obtenir plusieurs lignes ce n'est pas compliqué il faut juste moduler le nombre de cases par deux, si on dépasse 2 on va a la ligne suivante et on utilise mouseX et mouseY pour retrouver la case.



EDIT 1 : Les petits trucs qui peuvent amener des questions :

T = longueur du tableau
L = largeur d'une case
M = position X de la souris normé en cases
enCours = le clip en cours de drag

setChildIndex(ob,T-1); = affiche l'objet en cours au dessus des autres
if(M<T){ ... = vérifie que la souris est bien sur une case avant de relâcher (évite les bugs)
tab.indexOf(enCours) = retrouve l'index de l'objet en cours de drag dans le tableau (la case vide)

EDIT 2 : Nath> si tu veux l’ajouter à ton tuto ne te gêne pas, ceci dit cela tient plus de la manipulation de tableau qu'autre chose ;-)
EDIT 3 : Légère modification du code pour le rendre plus propre (rien qui change techniquement)

Fichier(s) joint(s)



#11 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 16 November 2012 - 13:20 PM

Re,

Petite mise à jour pour gérer la combinaison :

import flash.display.MovieClip;
import flash.desktop.Clipboard;
import flash.events.MouseEvent;

var c1:MovieClip = new C1();
var c2:MovieClip = new C2();
var c3:MovieClip = new C3();
var c4:MovieClip = new C4();
var V:MovieClip = new Victoire();

V.x = 250;
V.y = 250;

var tab:Array = [c1,c2,c3,c4];
var tabV:Array = [c4,c3,c2,c1];
var T:int = tab.length;
var L:int = c1.width;
var enCours:MovieClip;

for (var i:int=0; i<T;i++){
        var ob:MovieClip = tab[i];
        ob.addEventListener(MouseEvent.MOUSE_DOWN, attrape);
        ob.addEventListener(MouseEvent.MOUSE_UP, lache);
        ob.buttonMode=true;
        addChild(ob);
}
replace();

function attrape(e:MouseEvent):void{
        enCours = MovieClip(e.target);
        enCours.startDrag();
        setChildIndex(enCours,T-1);
}

function lache(e:MouseEvent):void{
        var M:int = mouseX/L;
        if(M<T){
                tab[tab.indexOf(enCours)] = tab[M];
                tab[M] = enCours;
                stopDrag();
                replace();
        }
}

function replace():void{
        for (var i:int=0; i<T;i++){
                tab[i].x = i*L;
                tab[i].y = 0;
        }
        for (var j:int=0; j<T;j++){
                if (tab[j]!=tabV[j])return;
        }
        addChild(V);
}

Pour le coup je suis sur qu'il existe plus simple que de refaire une boucle quand on replace les clips mais je vous laisse chercher ;-)

J'utilise un tableau de référence pour l'ordre de victoire (tabV).
Quand je replace les clips je compare les valeurs de chaque index des deux tableaux (tab et tabV).
Si une comparaison n'est pas vérifiée on ne va pas plus loin (return).
Sinon on affiche le clip de victoire (V).

Fichier(s) joint(s)



#12 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 16 November 2012 - 19:34 PM

Bon.... ben à première vue je suis encore arrivé après la guerre lol ;-)
Pas grave ça servira à ceux qui pourraient chercher la même chose..... :smile:

#13 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 16 November 2012 - 20:48 PM

Salut,

Tu n'as pas perdu ton temps M. Spi, pour ma part je suis preneur sur ta version non pas que la version de Nataly soit moins bonne mais ton code met plus familier et se rapproche de ce que j'ai plus ou moins déjà assimilé sur le forum.

Merci pour votre participation ;-) !

#14 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 16 November 2012 - 21:07 PM

Disons que la version de Nath est adaptée dans le cas où les objets sont positionnés en peu en vrac.
La mienne est spécifique à l'utilisation d'une grille, c'est à dire que tous les objets doivent être présentés sous la forme d'une grille (à une ou plusieurs dimensions), c'est ça qui permet de se simplifier la vie en utilisant les index d'un tableau, sinon cela aurait été bien plus compliqué à gérer.


Nath > j'ai parcouru ton tuto, je ne suis pas d'accord pour le cas de l'inventaire et de la grille ;-)
Pour moi dans ces deux cas on se simplifie la vie en utilisant des tableaux, mais c'est un avis perso....

Bon courage.

#15 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 17 November 2012 - 08:07 AM

Si Nataly désire ajouter d'autres exemples sur son tuto je peux suggérer ceci, ils peuvent être utile dans certains cas.

Fichier(s) joint(s)



#16 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 17 November 2012 - 09:44 AM

Hello M Spi,

Je tente d'ajouter une combinaison de résultat supplémentaire pour cela j'ai ajouté un 2ème Array

var tab:Array = [c2,c3,c4,c1];  // Mélange
var tabV:Array = [c1,c2,c3,c4];  // 1eme posibilité de résultat
var tabV2:Array = [c1,c3,c4,c2]; // 2eme posibilité de résultat
 
et modifier la fonction "replace"

function replace():void{
for (var i:int=0; i<T;i++){
  tab[i].x = i*L;
  tab[i].y = 0;
}
for (var j:int=0; j<T;j++){
  if (tab[j]!=tabV[j])return;
  else if (tab[j]!=tabV2[j])return;
}
addChild(V);
}
 
Je n'ai pas de message d'erreur mais ça ne fonctionne pas, j'ai également testé cela:

if (tab[j]!=tabV[j] || tab[j]!=tabV2[j])return;
 
mais pas de résultat non plus !?

#17 Nataly

    Community Jane

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 5783 messages

Posté 17 November 2012 - 10:11 AM

Non Spi tu n'arrives pas après la guerre, c'est moi qui n'ai pas trouvé le temps de venir commenter hier, et ce matin, pour le coup c'est moi qui ai un metro de retard. :)

Bon, tout est dit :
méthode SPI adaptée aux grilles, aux grand nombres d'objets. (des années de dev de moteur à tuile, ça laisse des traces :P )

méthode moi : liberté absolue à la création et à la modification. Les objets peuvent avoir des tailles différentes, sans intervalle régulier, être disposés comme on souhaite, et on peut modifier tout ça, ajouter ou supprimer sans plus jamais toucher au code.

Citation

EDIT 2 : Nath> si tu veux l’ajouter à ton tuto ne te gêne pas, ceci dit cela tient plus de la manipulation de tableau qu'autre chose ;-)
C'est vrai que ta solution n'utilise pas le hitTest, mais justement c'est super d'illustrer qu'une consigne qui semble avoir immanquablement recours aux tests de superposition peut être résolue avec uniquement des calculs.
Donc oui, je vais mettre un lien :Hola:


Citation

Nath > j'ai parcouru ton tuto, je ne suis pas d'accord pour le cas de l'inventaire et de la grille ;-)
Pour moi dans ces deux cas on se simplifie la vie en utilisant des tableaux, mais c'est un avis perso....

Avis que je partage, d'où le tbInventaire. ;-)
Si tu pensais à un tableau pour stocker les objets à déplacer, ds ce cadre ça ne sert à rien. Tj même objectif : moins je nomme et plus je peux modifier l'aspect sans toucher au code, mieux je me porte.

merci Cortho des suggestions. Je regarde tout ça, même si je ne vais sans doute pas plus charger ce pov' tuto :)


[edit] merci d'avoir parcouru le tuto et surtout ses exos : c'est principalement là qu'il y a des risques de grave égarement, vu qu'il faut penser à l'envers. Au lieu de se dire, j'ai un truc à faire , comment vais-je m'y prendre, on se dit : je veux m'y prendre comme ça… inventons une excuse, un alibi. C'est super casse gueule.
Le savoir est le seul bien qui s'accroit quand on le partage
une tartine de tutos

#18 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 17 November 2012 - 13:27 PM

@Cortho> normal que ça ne fonctionne pas, il suffit de traduire ton code pour t'en rendre compte.

for (var j:int=0; j<T;j++){
  if (tab[j]!=tabV[j])return;
  else if (tab[j]!=tabV2[j])return;
}

Fais une boucle de 0 à 4 (la longueur du tableau)
Si la valeur d'un des index de "tab" est différente de la valeur d'un des index de "tabV"
Ou si la valeur d'un des index de "tab" est différente de la valeur d'un des index de "tabV2"
Alors arrête la fonction (n'affiche pas le clip de la victoire).

Ce qui reviens à dire que pour gagner il faut que "tab" soit égal à la fois à "tabV" et à "tabV2" ;-)
Donc ça ne peux pas marcher puisque tu ne peux pas avoir deux combinaisons à la fois différentes et identiques.

Là il te faut inverser la logique et ne pas dire : "si un index de la combinaison est différent, ne gagne pas."
Mais : "si tous les index de la combinaison sont identique , gagne"

Et il faut le faire pour chaque combinaison séparément.

@Nath>

Citation

Si tu pensais à un tableau pour stocker les objets à déplacer, ds ce cadre ça ne sert à rien. Tj même objectif : moins je nomme et plus je peux modifier l'aspect sans toucher au code, mieux je me porte.

Bah en fait je me disais surtout que c'était illustrer le tuto avec un exercice qui certes fonctionne, mais qui n'est pas adapté à cette situation précise, un gars qui tombe dessus et qui veux faire un jeu (cas le plus courant d'utilisation d'un inventaire graphique) risque de ne pas partir dans le bon sens si il ne remet pas les choses dans leur contexte (celui démonstratif du tuto). A contrario je trouve que l'exemple de la guirlande est lui tout à fait adapté, tout comme celui du sapin. Peut être qu'une petite précision s'impose à cet endroit, juste pour dire que c'est un exemple de fonctionnement qui illustre le tuto mais pas une solution pérenne pour faire un jeu vidéo par exemple, où on va forcément utiliser un tableau, et où les items ne sont pas forcément ramassés à la souris. Il y a en fait très peu de jeux qui utilisent un système de "glisser/déposer" depuis la scène du jeu sur l'inventaire, de là c'est plus une "zone de stockage ou de tri" plutôt qu'un inventaire que tu propose, un peu comme prendre les objets et les ranger indifféremment dans une boite (retour à l'exemple du sapin). Mais bon comme toujours, chaque développeur vois les choses différemment et je peux me tromper ;-)

#19 Nataly

    Community Jane

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 5783 messages

Posté 17 November 2012 - 14:12 PM

Voir le messageMonsieur Spi, le 17 November 2012 - 13:27 PM, dit :

Bah en fait je me disais surtout que c'était illustrer le tuto avec un exercice qui certes fonctionne, mais qui n'est pas adapté à cette situation précise : un gars qui tombe dessus […]
… au lieu de l'aider à nager je le pousse à se noyer !
Comme tu as raison ! ;)

C'est pour ça qu'il ne faut surtout pas hésiter à dire les choses comme tu les vois.
Pinaille tant que tu veux sur les tutos, ça ne peut pas leur nuire.
Quant à moi mon objectif premier c'est d'aider, pas d'enfoncer. Je ne pourrais que t'être reconnaissante et… Si je ne me range pas à tes arguments, sois sans crainte : je le dirai.

justement… :D

Citation

Il y a en fait très peu de jeux qui utilisent un système de "glisser/déposer" depuis la scène du jeu sur l'inventaire,

Si tu y regardes de près, on déplace les objets d'un contenant (base est un clip) à un autre, et sur l'opération de retour, on change à nouveau de contenant. Du coup j'ai pensé que c'était tout bête à implémenter/décliner dans le cadre d'un point & clic. J'ai d'ailleurs hésité à permettre la navigation d'un contenant à l'autre via l'inventaire mais ça sortait de mon objectif : petits exos d'échauffement ocazou.

Citation

[…]pas une solution pérenne pour faire un jeu vidéo par exemple, où on va forcément utiliser un tableau, et où les items ne sont pas forcément ramassés à la souris
j'ai un jeu de classes qui gére du point & clic ultra complet : navigation de scène en scène, inventaire, objets utilisables dans diverses scènes et sous conditions, interactions entre tout ça, pérennité des décors (quand on revient ds une pièces on la retrouve ds l'état où on l'avait laissé)…
Il y a un seul tableau, dans la classe inventaire (et zéro getchild…). Effectivement c'est le parti pris ramassé à la souris qui permet ça.

Citation

Peut être qu'une petite précision s'impose à cet endroit
C'est pas peut-être, c'est sûr !
De toutes façons il ne me plaisait guère cet exo, j'ai eu du mal à le trouver et si j'avais eu les deux précédents il n'y serait même pas. Je sens qu'il va me donner du fil à retordre, screugneu :twisted:

Merci de ton aide :deal:
Le savoir est le seul bien qui s'accroit quand on le partage
une tartine de tutos

#20 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 17 November 2012 - 14:17 PM

Re,

Je suis en train de relire ton tuto, un truc qui serait bien dans ta démonstration du hitTestPoint, serait de donner la formule mathématique correspondante :

if (A.x<B.x+B.width && A.x>B.x && A.y<B.y+B.height && A.y>B.y)

Soit un test de collision entre un point et une surface.
Ca parrait annecdotique mais en fait c'est pratique si on veux faire varier la détection (décalage vis à vis de la surface par exemple).

Pour l'inventaire, j'utiliserai plus "boite de rangement", j'en parle dans mon précédent message, afin d'éviter la confusion avec un réel inventaire qui permet le tri, etc...

Bug sur la partie "intervertir les clips", quand on teste ton SWF, si je glisse l'étoile sur la petite étoile, la grande vient se replacer en vrac dans la barre du haut, normal ? Si j'en colle plusieurs (d'items) sur leurs emplacements respectifs, ils se mettent tous les uns au dessus des autres dans la zone du haut. Et si les items se superposent (petit et grands) l'interaction ne se fait pas tant que ce n'est pas la souris qui est sur l'item du bas.

#21 Nataly

    Community Jane

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 5783 messages

Posté 17 November 2012 - 14:29 PM

'fo que je file.

De retour je me précipite sur tes retours et balade les messages ds le sujet dédié

++ :)
Le savoir est le seul bien qui s'accroit quand on le partage
une tartine de tutos

#22 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 17 November 2012 - 14:35 PM

Citation

Du coup j'ai pensé que c'était tout bête à implémenter/décliner dans le cadre d'un point & clic.

A part certains jeux précis (cas de l'exemple de la poubelle) il n'y a pas d'interaction directe entre item de l'inventaire et jeu, dans un point & clic classique on cliques sur un objet et il vient se loger dans l'inventaire, pas de glisser/déposer, mais justement pointer et cliquer, et pour l'utiliser on le sélectionne dans l'inventaire via un clic (on le prend en main) et on cliques sur un objet de la scène pour activer ce qu'on tient à la main (par exemple une clé). Donc tout dépend non pas des objets mais de la souris combinée à l'objet tenu en main. C'est beaucoup plus simple pour le joueur que de glisser/déposer, surtout lorsque l'inventaire est visible via un panneau d'interface indépendant qui prend tout l'écran, ça oblige à attraper l'item dans l'inventaire, faire une contorsion pour fermer l'inventaire avec l'objet "en main" (sans lâcher la souris), puis ensuite le glisser au bon endroit sur la scène du jeu, et inversement. C'est pour ça qu'il y a très peu de glisser/déposer pour la gestion d'inventaire, tout du moins en ce qui concerne l'interaction scène du jeu/interface, les actions sont générées par la souris et l'objet en mémoire (dit "tenu en main"). En revanche au sein de l'interface (panneau inventaire) on va utiliser du glisser déposer pour ranger son sac, comme on dit, et trier les objets, mais on reste sur le panneau d'inventaire et généralement il est présenté .... sous forme de grille ;-) C'est avant tout un problème de Gameplay, surtout lorsqu'on va utiliser beaucoup d'objets, les jeux limités à une dizaine d'objets ne sont pas forcément concernés, l'inventaire peut être toujours visible en intégralité donc accessible facilement, mais c'est assez rare comme jeux, généralement les point & click utilisent beaucoup d'objets qu'il faut parfois combiner pour trouver la solutions (j'ai un torchon, un manche de pioche, de l'essence et un briquet et je dois les combiner pour faire une torche qui va allumer la pièce).

Bon maintenant je chipote hein :P

#23 Nataly

    Community Jane

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 5783 messages

Posté 17 November 2012 - 17:19 PM

Hey Spi !!

tu voudrais pas ajouter une réponse vide au sujet ici, pour que je puisse l'éditer ensuite et y regrouper tes retours, sous ton pseudo ds l'idée de reconstituer la conversation qui trolle un peu le sujet Cortho ?
Le savoir est le seul bien qui s'accroit quand on le partage
une tartine de tutos

#24 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 17 November 2012 - 17:26 PM

Heuuuu si tu veux, mais bon ce n'est qu'un échange d'avis je sais pas si c'est utile de le remettre dans le thread du tuto, en tous les cas c'est fait.

#25 Nataly

    Community Jane

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 5783 messages

Posté 17 November 2012 - 18:35 PM

T'as raison (encore !… pfff)
C't'un m#¡#@ sans nom de reconstituer… j'abandonne :mrgreen:

Et j'arrête de troller… :jesors:
Le savoir est le seul bien qui s'accroit quand on le partage
une tartine de tutos

#26 Nataly

    Community Jane

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 5783 messages

Posté 17 November 2012 - 20:10 PM

Voir le messagecortoh, le 17 November 2012 - 08:07 AM, dit :

Si Nataly désire ajouter d'autres exemples sur son tuto je peux suggérer ceci, ils peuvent être utile dans certains cas.

euhhhh… j'ai raté un truc où c'est la même chose :huh:
Le savoir est le seul bien qui s'accroit quand on le partage
une tartine de tutos

#27 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 17 November 2012 - 21:33 PM

Oui c'est la mème chose Nataly mais je pointais dans ces exemples les limites de déplacement des drags qui peuvent être utiles dans certains cas ;-) !

#28 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 17 November 2012 - 21:58 PM

Et bien en fait comme ceci ça fonctionne mais bon c'est déroutant :eusa_doh: !

if (tab[j]!=tabV[j] && tab[j]!=tabV2[j])return;
 


Sinon, je suis entrain de me prendre la tête pour disposer les clips en grille comme ceci:

var tab:Array =[
[c2,c3],
[c4,c1]
];
Si je ne dis pas de bêtise il me faut ajouter une variable supplémentaire pour la hauteur "height" et modifier la boucle existante :?: :idea:

Je suis repartie relire le tuto ici pour essayer de capter le meli-melo

#29 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 18 November 2012 - 13:03 PM

Pour faire deux lignes il y a plusieurs méthodes, la plus simple dans ton cas (peu de cases dans le tableau) est de modifier d'abord la fonction de replacement :

function replace():void{
        for (var i:int=0; i<T;i++){
                tab[i].x = i*L;
                tab[i].y = 0;
                if(i>1) {
                        tab[i].x = (i-2)*L;
                        tab[i].y = L;
                }
        }
        for (var j:int=0; j<T;j++){
                if (tab[j]!=tabV[j])return;
        }
        addChild(V);
}
 

Je commence par replacer les clips en ligne.
Puis si "i" est supérieur à 1 (donc égal à 2 ou 3), je replace les clips à la ligne du dessous.

Et de ne pas oublier de modifier la fonction "relache" pour remettre les clips aux bons index :

function lache(e:MouseEvent):void{
        var Mx:int = mouseX/L;
        var My:int = mouseY/L;
        if(My>0) Mx+=2;
        tab[tab.indexOf(enCours)] = tab[Mx];
        tab[Mx] = enCours;
        stopDrag();
        replace();
}

Je récupère une variable par axe (Mx et My) pour la position de la souris.
Si la souris est sur la ligne du dessous (My>0) j'ajoute le nombre de cases de la ligne précédente (2) à Mx.


Il devrait y avoir une piste plus simple en utilisant un modulo, à chercher ;-)

#30 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 18 November 2012 - 14:20 PM

Salut M Spi,
Merci pour ta réponse, j'ai compris le principe mais j'avoue que ce n'est pas encore très évident à assimiler au niveau de l'écriture.
Je vais plancher dessus et tenter de me familiariser avec ce script en créant une grille de 5 x 5, normalement ça devrait le faire ;-) !
Je post mon résultat dès terminé.

#31 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 18 November 2012 - 22:06 PM

Bon effectivement pas extra pour créer plusieurs lignes, pas trouvé le moyen de faire plus de 2 lignes, un peu enragé :angry: pour le temps passé mais bon c'est plaisant tout de même ^_^ , bonne soirée à tous !

#32 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 19 November 2012 - 03:15 AM

Ok, bon si tu veux partir sur des grilles plus grandes il faut s'y prendre autrement, jusque là on était sur de la bidouille qui convenant à des petits tableaux.

Voici la solution pour des grilles de n'importe quelle taille.

import flash.display.MovieClip;
import flash.desktop.Clipboard;
import flash.events.MouseEvent;

var i:int
var tab:Array=[];
var T:int = 25;
var L:int = 55;
var enCours:MovieClip;

for (i;i<T;i++){
        var c:Case = new Case();
        c.addEventListener(MouseEvent.MOUSE_DOWN, attrape);
        c.addEventListener(MouseEvent.MOUSE_UP, lache);
        c.buttonMode=true;
        c.chiffre.text = (i+1).toString();
        c.chiffre.mouseEnabled = false;
        tab.push(c);
        addChild(c);
}

affiche();

function affiche():void{
        for (i=0; i<T;i++){
                tab[i].x= i%5*L;
                tab[i].y= int(i/5)*L;
        }
}

function attrape(e:MouseEvent):void{
        enCours = MovieClip(e.target);
        enCours.startDrag();
        setChildIndex(enCours,T-1);
}

function lache(e:MouseEvent):void{
         var index:int = int(mouseX/L)+int(mouseY/L)*5;
        tab[tab.indexOf(enCours)] = tab[index];
        tab[index] = enCours;
        stopDrag();
        affiche();
}
 

Je commence par faire 25 clips "case", chacun contient un texte dynamique et les écouteurs pour le drag & drop.
Je les pousses les uns à la suite des autres dans le tableau "tab" (ma grille), et je les ajoutes à l'affichage.

Pour l'affichage du tableau à une seule dimension (autrement dit une liste) sous forme de grille à deux dimensions, j'utilise une petite astuce avec un modulo (%). Ainsi, je parcours le tableau et je donne une position sur X à chaque case, il s'agit de la valeur de "i" (de 0 à 24) limitée à 5 (le nombre de colonnes d'une seule ligne) multipliée par la largeur d'une case. Pour Y je prend la valeur entière de "i" divisée par 5 (le nombre de lignes), on prend la valeur entière car la division ne renvoie pas toujours un chiffre rond et nous ce qu'on veut c'est la position de la ligne.

Enfin, dans la fonction "lache" je dois récupérer l'index de la grille où se trouve la souris, pour ça c'est très simple, il s'agit de l'entier de la position de la souris sur X + l'entier de la position de la souris sur Y multiplié par le nombre de lignes, par exemple avec une grille de 5*5 :

Si ma souris est à la position :

Mx = 2;
My = 3;

Alors la case de la grille 2D correspondante est : 2+3*5 = 17;
Il s'agit donc de l'index 17 dans mon tableau à une dimension.

L'inversion des index n'a pas changé, on reste sur le même principe.

C'est tout simple mais ça demande de connaître le modulo, je savais bien qu'il y avait une piste avec ça, du coup c'est adapté pour toutes les grilles avec moins de code, plus simple je ne pense pas avoir en stock ;-)

Je te laisses chercher pour la gestion de la combinaison et de la victoire...

Fichier(s) joint(s)



#33 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 19 November 2012 - 07:04 AM

Bonjour M Spi,
Merci pour ton travail, j'ai imprimé ton post pour le lire et le déchiffrer dans la journée car il faut que je parte bosser, je serais bien resté devant le pc ce matin :D, je planche dessus dès ce soir, merci encore à toi ;) !

#34 Nataly

    Community Jane

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 5783 messages

Posté 19 November 2012 - 14:42 PM

Quant à la soluce alternative… hi hi… elle fonctionne quelque soit la disposition (pardon ! il faut ajouter une ligne pour tester les y ocazou)

C'était juste pour la ramener :P
Le savoir est le seul bien qui s'accroit quand on le partage
une tartine de tutos

#35 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 19 November 2012 - 19:09 PM

Salut,
Je ne sais pas comment vous faite pour sortir des codes de ce genre, il vous faut postuler à la Naza :D mais c'est à ce décourager en tout cas chapeau bas :Hola: !
J'ai regarder le code et on utilise plus d'Array c'est dommage car on ne peut pas dans ce cas utiliser des clips avec forme ou image comme l'exemple de Nataly et pour la gestion de la combinaison c'était bien fait aussi.
Je bidouille pour utiliser le modulo sur le code précédent ce qui serait mas mal, ou inversement remplacer la var c par un Array sur la dernière version du code.

#36 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 19 November 2012 - 19:43 PM

Citation

J'ai regarder le code et on utilise plus d'Array c'est dommage car on ne peut pas dans ce cas utiliser des clips avec forme ou image comme l'exemple de Nataly et pour la gestion de la combinaison c'était bien fait aussi.

Il faut te libérer des choses qu'on te propose, ce n'est pas parce que j'utilise une boucle pour remplir le tableau (Array) que tu es obligé de faire la même chose, cette partie ne joue en rien sur le reste (inversion des index, mise en forme sous la forme d'une grille en deux dimensions ect...).

Crée autant d'objets de formes diverses que tu veux, mets les dans un tableau comme on l'avais fait avec les premiers codes et ça marchera pareil, le tableau est le même :

var tab:Array = [c1,c2,c3,c4,c5,c6,c7,c8,c9, ......................];


En gros :

for (i;i<T;i++){
                var c:Case = new Case();
                c.addEventListener(MouseEvent.MOUSE_DOWN, attrape);
                c.addEventListener(MouseEvent.MOUSE_UP, lache);
                c.buttonMode=true;
                c.chiffre.text = (i+1).toString();
                c.chiffre.mouseEnabled = false;
                tab.push(c);
                addChild(c);
}

Revient au même que :


var c1:MovieClip = new C1();
var c2:MovieClip = new C2();
var c3:MovieClip = new C3();
var c4:MovieClip = new C4();
var c5:MovieClip = new C5();
var c6:MovieClip = new C6();
var c7:MovieClip = new C7();
var c8:MovieClip = new C8();
var c9:MovieClip = new C9();
var c10:MovieClip = new C10();
var c11:MovieClip = new C11();
var c12:MovieClip = new C12();
var c13:MovieClip = new C13();
var c14:MovieClip = new C14();
var c15:MovieClip = new C15();
var c16:MovieClip = new C16();
var c17:MovieClip = new C17();
var c18:MovieClip = new C18();
var c19:MovieClip = new C19();
var c20:MovieClip = new C20();
var c21:MovieClip = new C21();
var c22:MovieClip = new C22();
var c23:MovieClip = new C23();
var c24:MovieClip = new C24();
var c25:MovieClip = new C25();

var tab:Array = [c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24,c25];

for (var i:int=0; i<T;i++){
                var ob:MovieClip = tab[i];
                ob.addEventListener(MouseEvent.MOUSE_DOWN, attrape);
                ob.addEventListener(MouseEvent.MOUSE_UP, lache);
                ob.buttonMode=true;
                addChild(ob);
}
 

La différence c'est que c'est plus rapide à écrire et que je n'utilise qu'un seul clip que je duplique au lieu d'en faire 25 différents.

Pour info, dans mon code avec la boucle j'utilise bien un tableau, j'y pousse simplement les clips au fur et à mesure que je les crée à l'aide de :

tab.push(c);

Je remplis le tableau à l'aide de la boucle au lieu de le remplir à la main, mais le résultat est le même.

#37 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 19 November 2012 - 19:51 PM

Alors c'est ok le modulo fonctionne correctement en utilisant le code précédent reste à voir si pas de soucis particulier.
Je garde tout de même sous le coude la dernière méthode qui est vraiment bien pensé.

#38 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 19 November 2012 - 19:54 PM

Désolé M Spi nos réponses se sont croisées, j'ai monté le script dans ce sens:

var T:int = tab.length;
var L:int = c1.width;
var enCours:MovieClip;
for (var i:int=0; i<T;i++){
var ob:MovieClip = tab[i];
ob.addEventListener(MouseEvent.MOUSE_DOWN, attrape);
ob.addEventListener(MouseEvent.MOUSE_UP, lache);
ob.buttonMode=true;
addChild(ob);
}
affiche();
function affiche():void{
for (i=0; i<T;i++){
var t:Object = tab[i];
t.x= i%5*L;
t.y= int(i/5)*L;
}
}
function attrape(e:MouseEvent):void{
enCours = MovieClip(e.target);
enCours.startDrag();
setChildIndex(enCours,T-1);
}
function lache(e:MouseEvent):void{
var Mx:int = mouseX/L;
var My:int = mouseY/L;
var index:int = Mx+My*5;
tab[tab.indexOf(enCours)] = tab[index];
tab[index] = enCours;
stopDrag();
affiche();
}
 


#39 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 20 November 2012 - 07:19 AM

J'ai remarqué quelque soit la taille de la grille que le dernier clip de la grille reste au premier plan si on porte un clip dessus :?: :huh:

#40 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 20 November 2012 - 13:52 PM

Tu dois avoir une erreur quelque part car je n'ai pas ce comportement sur les tests que je t'ai envoyé.
Ce qui permet de passer le clip saisi au dessus des autres est la ligne suivante :

setChildIndex(enCours,T-1);

L'index du clip "enCours" est égal à la longueur du tableau -1.
Un tableau commence toujours à l'index 0, mais le calcul de la longueur d'un tableau commence à 1 (il compte le nombre d'index).
Donc on retire 1 pour ne pas dépasser la limite du tableau.

#41 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 20 November 2012 - 19:15 PM

Merci M Spi ;-) , effectivement c'est bien ça et je l'avais pourtant appris sur le wiki !

#42 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 21 November 2012 - 19:33 PM

Salut,
Pour la fonction "replace" si bonne combinaison je voudrais relancer le code j'ai donc potassé de nombreuses pages sur les array(s) et j'ai découvert pas mal de choses intéressante le sortOn(); rerverse(); splice(); etc...
mais rien pour restituer et afficher l'array de départ "tab" ou éventuellement un autre array "tab2"par exemple à moins qu'il faille réinitialiser le code ?.

function replace():void{
for (var j:int=0; j<T;j++){
if (tab[j]!=tabV[j])return;
}
addChild(V);
(tab);
}
 


#43 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7013 messages

Posté 21 November 2012 - 20:42 PM

Je n'ai pas compris ta question.

Arrivé à ce stade, nous t'avons donnés pas mal d'infos, et tu ne semble pas réussir à les assimiler pour faire ce que tu veux. Cela indique qu'il te manque certaines bases indispensables pour aller plus loin, notamment concernant les tableaux et la manière dont on s'en sert, ne le prend pas mal c'est juste une constatation faite au fil de tes réponses.

Ceci par exemple, ne veut rien dire :

(tab);

Plus haut tu indique qu'on utilise plus d'Array dans les formules, alors que c'est la base de tout le programme.
etc..

J'insiste sur le fait qu'il n'y a rien de compliqué dans les formules données (en dehors de l'astuce du modulo, et encore, mais ce n'est pas ce qui te pose problème ici), elles demandent d'avoir des connaissances de base sur les tableaux, les variables, la liste d'affichage, les boucles et les fonctions, des choses indispensables si tu veux écrire un code, que ce soit en AS ou dans un autre langage.

Mon conseil serait donc de te faire quelques tutoriels sur ces points avant d'aller plus loin, histoire de commencer par le début.
Puis de poser sur papier un descriptif clair de ce que tu veux faire.
Et enfin, au final, d'essayer de le transcrire en code avec les bases que tu aura acquis.

La programmation n'est pas un fatras de signes cabalistiques qu'on balance au hasard entre la poire et le fromage pour voir ce que ça fait, construire un programme est une discipline qui fait surtout appel à la logique et qui demande une grande précision quand aux termes qu'on utilise.

Ce n'est donc pas qu'un problème de "code", mais de logique avec laquelle tu construit ton programme.
Munis toi d'un papier, d'un stylo, éteins l'ordinateur et écrit précisément ce que tu veux faire dans ta langue maternelle.
Quand tout te paraitra clair et propre, rallume l'ordi et essayes de construire ton programme en lisant ton papier.

#44 cortoh

  • Members
  • PipPipPipPipPipPipPipPip
  • 635 messages

Posté 21 November 2012 - 20:59 PM

Ok M Spi, je vais tenter de suivre tes conseils.



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

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