• User Newbie

    Dividere una bitmap e muovere i pezzi

    Buongiono a tutti,
    vorrei creare un giochetto per il mio nipotino(una specie di puzzle) e contemporaneamente imparare qualcosa di più da as3.
    Ho copiato da internet il codice che segue con il quale si ottiene lo spezzettamento di una bitmap.
    Questo codice,tuttavia, non consente di trascinare i singoli pezzi. Ho tentato
    di aggiungere codice adeguato ma nonostante vari tentativi mi riesce di spostare solo un pezzo.
    C'è qualcuno che mi possa aiutare nel senso da me desiderato?
    Ringrazio sentitamente ,feur.


    // Impostiamo le variabili per il numero di tasselli
    var pezzi_h:uint
    var pezzi_v:uint
    // Creiamo lo sprite dove mostreremo i tasselli
    var sprite_tasselli:Sprite = new Sprite();

    imposta_divisione("NONNO.jpg",3,3)
    function imposta_divisione(quale:String,po:uint,pv:uint):void{
    // impostiamo il numero di pezzi orizzontali
    pezzi_h = po
    // impostiamo il numero di pezzi verticali
    pezzi_v = pv
    var carica_foto:Loader = new Loader()
    var richiesta:URLRequest = new URLRequest(quale)
    carica_foto.contentLoaderInfo.addEventListener(Event.COMPLETE,dividi_foto)
    carica_foto.load(richiesta)
    }
    //*************************************************************
    function dividi_foto(chi:Event):void{
    // creiamo una copia dell'immagine
    var immagine:Bitmap = Bitmap(chi.target.loader.content);
    // stabiliamo larghezza e altezza di ogni pezzo
    var l_pezzo = Math.floor(immagine.width/pezzi_h)
    var a_pezzo = Math.floor(immagine.height/pezzi_v)
    // tagliamo i vari pezzi
    for(var r:uint=0;r<pezzi_h;r++){ // percorriamo tutte le righe
    for(var c:uint=0;c<pezzi_v;c++){ // e tutte le colonne
    // creiamo una bitmap con le dimensioni del pezzo del puzzle
    var img_pezzo:Bitmap = new Bitmap(new BitmapData(l_pezzo,a_pezzo));
    // copiamo i pixel dall'immagine originale al pezzo creato
    img_pezzo.bitmapData.copyPixels(immagine.bitmapData,new Rectangle(rl_pezzo,ca_pezzo,l_pezzo,a_pezzo),new Point(0,0));
    // creiamo un nuovo sprite
    var sprite_pezzo:Sprite = new Sprite();
    sprite_pezzo.x = Math.random()*500
    sprite_pezzo.y = Math.random()*400
    // inseriamo nello sprite la bitmap creata
    sprite_pezzo.addChild(img_pezzo);
    // inseriamo lo sprite "sprite_pezzo" dentro a "sprite_tasselli"
    sprite_tasselli.addChild(sprite_pezzo)
    }
    }
    // aggiungiamo sprite_tasselli allo stage
    addChild(sprite_tasselli)
    //*****MUOVE SOLO UN PEZZO

    sprite_pezzo.addEventListener(MouseEvent.MOUSE_DOWN, mouseDow)
    function mouseDow(event:MouseEvent):void {
    sprite_pezzo.startDrag();
    }
    sprite_pezzo.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
    function mouseReleased(event:MouseEvent):void {
    sprite_pezzo.stopDrag();
    }
    //**********************************************************************
    }


  • User

    Ciao

    Devi applicare lo startDrag() e stopDrag() al pezzo che ha generato l'evento ovvero quello effettivamente cliccato.

    Poi, il pezzo cliccato dovrebbe visualizzarsi sopra tutti gli altri quindi ti serve fare un calcolo sui livelli virtuali che si creano (in realtà tutti i pezzi sono su un'unico livello ma occupano posizioni di visualizzazione diversi).

    Ora non stò a spiegarti il concetto dei livelli di visualizzazione della DisplayList in AS3 ma ho fatto un'aggiunta sul codice che hai postato in modo che il pezzo cliccato si possa spostare e al mouseDown venga visualizzato sopra tutti gli altri.
    Ho creato poi una variabile numerica che viene utilizzata per identificare il livello di visualizzazione e in questo modo, puoi aumentare il livello di difficoltà del puzzle semplicemente incrementando il numero di pezzi passati alla funzione: "imposta_divisione"

    [PHP]var pezzi_h:uint;
    var pezzi_v:uint;
    var sprite_tasselli:Sprite = new Sprite();
    var sprite_pezzo:Sprite = new Sprite();

    imposta_divisione("foto.jpg",3,3);
    function imposta_divisione(quale:String,po:uint,pv:uint):void
    {
    pezzi_h = po;
    pezzi_v = pv;
    var carica_foto:Loader = new Loader();
    var richiesta:URLRequest = new URLRequest(quale);
    carica_foto.contentLoaderInfo.addEventListener(Event.COMPLETE,dividi_foto);
    carica_foto.load(richiesta);
    }

    function dividi_foto(chi:Event):void
    {
    var immagine:Bitmap = Bitmap(chi.target.loader.content);
    var l_pezzo = Math.floor(immagine.width / pezzi_h);
    var a_pezzo = Math.floor(immagine.height / pezzi_v);
    for (var r:uint=0; r<pezzi_h; r++)
    {
    for (var c:uint=0; c<pezzi_v; c++)
    {
    var img_pezzo:Bitmap = new Bitmap(new BitmapData(l_pezzo,a_pezzo));
    img_pezzo.bitmapData.copyPixels(immagine.bitmapData,new Rectangle(rl_pezzo,ca_pezzo,l_pezzo,a_pezzo),new Point(0,0));
    sprite_pezzo = new Sprite();
    sprite_pezzo.x = Math.random() * 500;
    sprite_pezzo.y = Math.random() * 400;
    sprite_pezzo.addChild(img_pezzo);
    sprite_tasselli.addChild(sprite_pezzo);
    }
    }
    addChild(sprite_tasselli);
    sprite_tasselli.addEventListener(MouseEvent.MOUSE_DOWN, sposta);
    sprite_tasselli.addEventListener(MouseEvent.MOUSE_UP, rilascia);
    }
    function sposta(evento:MouseEvent):void
    {
    var topLevel:uint = pezzi_h * pezzi_v - 2;
    var oggetto:DisplayObject = DisplayObject(evento.target);
    sprite_tasselli.setChildIndex(oggetto, numChildren + topLevel);
    evento.target.startDrag();
    }
    function rilascia(evento:MouseEvent):void
    {
    evento.target.stopDrag();
    }[/php]

    Non è finito.
    A mio parere l'ideale sarebbe fare in modo che se il pezzo viene posizionato correttamente si attacca allo stage e viene disattivato lo startDrag().
    Si potrebbe mettere sotto la foto in trasparenza e fare una specie di griglia invisibile dove i pezzi vanno ad allinearsi correttamente (hitArea).

    Non ho molto tempo per starci su ma se ti interessa approfondire posso fornirti di alcuni esempi sull'uso di hitArea e hitTestObject.

    ciao


  • User Newbie

    Carissimo,
    ti ringrazio infinitamente, sei stato di una gentilezza e disponibilità non comune.
    Da tanto cercavo di realizzare il gioco e di capirne il meccanismo, la tua risposta mi ha dato degli indirizzi di studio con cui mi devo cimentare.
    Per ora, quindi, non voglio appesantirmi con ulteriori problemi anche perchè il mio cervello non è più giovane.
    Ti ringrazio ancora, feur.


  • Super User

    Sleter sei un mostro... Ho fatto dei tentativi ma seguendo una strada sbagliata, bravissimo.