Oppure

Loading
29/06/10 11:49
Sal47
Buongiorno a tutti,
prendendo spunto da tanti esempi in rete, sto ricostruendo, molto modestamente, un Puzzle per ricomporre un'immagine in formato 640 x 480 suddivisa in 48 tessere (6 righe x 8 colonne) e il tutto sembra funzionare.
Però vorrei che, uscendo dal gioco senza aver completato il puzzle, al successivo riavvio venissero ricaricate le tessere che nella precedente sessione erano già state correttamente posizionate.
Per fare ciò ho provato:
a) all'uscita dal gioco: ad utilizzare "savepicture" per ciascuna delle 48 tessere/picturebox di cui è composto il puzzle e salvare così altrettanti file .bmp;
b) al successivo riavvio del gioco: pensavo di caricare in ciascuna delle 48 tessere questi file bmp e non quelli casualmente caricati (vds. da istruzione Randomize della Sub Puzzle del listato) e ovviamente inserendo una istruzione, ora mancante, per scegliere se riprendere il gioco da dove era stato interrotto o iniziarne uno nuovo.

Il problema è che provando, ad es., a caricare uno dei file bmp in una picturebox di prova (nel form è la Picture4) l'immagine che ne risulta è "sfocata, con colori strani" e quindi inutilizzabile. Anche salvando le 48 tessere in formato jpg il risultato non cambia.
Potreste darmi qualche indicazione su come risolvere il problema?

In alternativa pensavo di inserire un secondo controllo ImageList in cui caricare, all'uscita dal gioco, le 48 tessere con "Set imgX = ImageList2.ListImages.Add(e + 1, , Picture2(e).Image)" ma con questo sistema mi sembra che le immagini vengano sì caricate nel controllo ma solo temporaneamente e non salvate in modo che nella proprietà "Personalizzate\Immagini" del controllo io possa poi ritrovarle ed utilizzarle al riavvio. C'è forse un sistema per salvare le immagini caricate nell'ImageList con Set ?

Allego nel file Puzzle.zip i form e il listato (che prego di voler scusare per la loro semplicità;).
Grazie per l'eventuale graditissimo aiuto.
Sal47
aaa
29/06/10 14:17
mikesoft220594
Io ti consiglierei di creare un file di testo con la funzione di un semplice array... Cioè, mi spiego meglio, ho guardato il tuo source è ho visto che alla fine della sub "Puzzle" hai messo una FOR che seleziona una picturebox alla volta ed estrae una immagine a caso (tramite il random) dall'imagelist. Quindi potresti aggiungere una semplice ListBox nella quale (per ogni PictureBox) aggiungi un elemento con l'indirizzo dell'ImageList.
quindi il codice verrebbe così:
For e = 0 To 47
Picture2(e).Cls
upp:
Randomize
z = Rnd * 47
If pic1(z) = 777 Then GoTo upp ' pic1(z) >??
Picture2(e).Picture = ImageList1.ListImages(z + 1).ExtractIcon
List1.AddItem z+1 'Aggiunge l'indice dell'ImageList alla lista
pic1(z) = 777
DoEvents
Next e

per poi salvarla in un semplice file testo(vedi progetto allegato).

Poi, alla riapertura del programma ridividi l'immagine originale in 47 pezzi e li memorizzi nell'imagelist, tenti di caricare il file nella listbox, se nn esiste vuol dire che non ci sono partite sospese, altrimenti carichi il file di testo(vedi sempre progetto allegato) nella lista e poi la leggi e carichi il numero contenuto nella lista nella picturebox .
Quindi il codice vene così:

sub LeggiPuzzleDaList()
dim a as long
dim Index as long
Dim imgX As ListImage
'Dim NomeImmag As String
Static xxx As Integer
Static yyy As Integer
xxx = 0
yyy = 0
For e = 0 To 47
Picture2(e).PaintPicture Picture1.Picture, 0, 0, 80, 80, 80 * xxx, 80 * yyy, 80, 80
xxx = xxx + 1: If xxx = 8 Then xxx = 0: yyy = yyy + 1
Set imgX = ImageList1.ListImages.Add(e + 1, , Picture2(e).Image)
' * la riga seguente servirebbe per mostrare i 48 pezzi prelevandoli
' * dall' ImageList1 in cui devono essere caricati
' Picture2(e).Picture = ImageList1.ListImages(e + 1).Picture
Next e
''''Recupero index dalla lista
if ReadList(List1,app.path & "\mem.txt";)=true then 'Il file e stato caricato (vedi file allegato)
for a=0 to list1.listcount-1
index=val(list1.list(a))
picture2.picture=ImageList1.ListImages(index).ExtractIcon
next a
end if
''''
end sub

e per salvare la lista devi solo richiamare questa sub quando chiudi il programma.

sub SalvaPuzzle()
call WriteList(List1,app.path & "\mem.txt"
end sub

aaa
29/06/10 16:07
Alfonso
Non ho provato il codice di mikesoft220594 ma mi sembra che registri solo lo stato iniziale del puzzle.
Per registrare un certo momento del gioco puoi provare questa soluzione.
Per memorizzare l'immagine contenuta nelle picture box ho usato il tag delle picturebox e la variabile tmpTag per lo scambio.

Quando attribuisci l'immagine random assegni anche al tag della PictureBox il numero che è stato estratto.
Picture2(e).Picture = ImageList1.ListImages(z + 1).ExtractIcon
Picture2(e).tag = z + 1


Quando scambi con il MouseDown le immagini
MouseIcon = Picture2(Index).Picture
tmpTag= Picture2(Index).Tag

Picture2(i) = Picture2(Index)
Picture2(i).tag = Picture2(Index).tag
Picture2(Index) = MouseIcon
Picture2(Index).tag = tmpTag


Per salvare
For Index = 0 To 47
salvi il valore Picture2(Index).tag

Per ricomporre
For Index = 0 To 47
Picture2(Index).tag= valore registrato
Picture2(Index ).Picture = ImageList1.ListImages(Picture2(Index).tag).ExtractIcon
aaa
29/06/10 17:34
Sal47
Salve,
ringrazio mikesoft220594 ed Alfonso per aver avuto la pazienza di "guardare" tutto il mio post e per i veloci suggerimenti. Mi studierò quanto suggeritomi e vi farò sapere.
Ancora grazie.
Sal47
aaa
29/06/10 21:24
mikesoft220594
E' vero, ho commesso un grave errore! :) Comunque, ringrazio Alfonso per avermi corretto! Anche se penso che anche il metodo di Alfonso abbia bisogno delle "Funzioni" da me postate(per salvare e leggere un file)... Comunque, scusatemi ancora.:rotfl:
aaa
01/07/10 9:47
Sal47
Buongiorno a tutti; allora ho inserito:
- un MsgBox con l'opzione per "NuovoPuzzle/Puzzle già iniziato";
e solo dopo molti tentativi:
- un ListBox (List1) in cui scrivere gli indici:
. casuali, per un Nuovo Puzzle;
. consecutivi (per prova da 1 a 48) che io ho precedentemente scritto in un file
App.Path & "\PuzzleIniziato".
Così se scelgo "NuovoPuzzle" vengono caricate le tessere in ordine casuale, e se scelgo "Puzzle già iniziato" vengono caricate le tessere nel modo corretto, come se avessi già risolto il puzzle.
E quì mi sono arenato. In particolare non riesco a capire come salvare i vari indici in un momento qualsiasi della ricomposizione del puzzle e quindi scriverli nel file "\PuzzleIniziato" al posto di quelli consecutivi da me scritti a titolo di prova.
Potete darmi ancora una "mano" ? Allego il nuovo file Puzzle_1.zip.
Grazie infinite.
Sal47
aaa
01/07/10 10:31
Alfonso
Hai interpretato male il mio primo suggerimento

tmpTag deve essere dichiarato integer nella sezione dichiarazioni del form e non deve essere un array. Ha una funzione simile alla i che viene usata all'interno della routine Picture2_MouseDown

Quando scambi con il MouseDown le immagini
If MousePointer = 0 Then
    MouseIcon = Picture2(Index).Picture
    tmpTag= Picture2(Index).Tag ' prende nota dell'indice della bitmap nel controllo picture
    ...............
else
    Picture2(i) = Picture2(Index)
    Picture2(i).tag = Picture2(Index).tag ' dopo aver scambiato l'immagine scambia anche l'indice della stessa
    Picture2(Index) = MouseIcon
    Picture2(Index).tag = tmpTag ' attribuisce l'indice dell'immagine scambiata
    ...................
end if

Per salvare (dopo aver aperto il file)
   For i = 0 To 47
      Print #1, Picture2(i).Tag ' salva l'indice dell'immagine contenuta nella picture i
   Next i

Per richiamare (dopo aver aperto il file)
   For i = 0 To 47
      Line Input #1, Text ' estrae l'indice dell'immagine che sarà della picture i
      Picture2(i).Tag = Text
      Picture2(i).Picture = ImageList1.ListImages(CInt(Text)).Picture
   Next
aaa
02/07/10 10:28
Sal47
Buongiorno Alfonso, ti prego di avere pazienza:
- ho dichiarato "tmpTag as integer" nella Sez. dich. del form (dopo Option Explicit):
- in base alla preced. tua risposta, nell'attribuire l'immagine random ho assegnato anche
al tag della PictureBox il numero estratto subito dopo l'istruzione
"Picture2(e).Picture = ImageList1.ListImages(z + 1).ExtractIcon" e cioè:
Picture2(e).Tag = z + 1
- per salvare il file dopo averlo aperto:
    Private Sub cmdEsci_Click(Scelta As Integer)
    If Scelta = 0 Then GoTo 1
    If Scelta = 1 Then
        Open App.Path & "\PuzzleIniziato" For Output As #1
        For I = 0 To 47
            Print #1, Picture2(I).Tag
        Next I
    End If
    1:
    Unload Me
    End Sub
- per richiamare il file dopo averlo aperto:
    Private Sub ApriFileChiusuraPrec()
    Dim I
    Dim Text As String
    List1.Clear
    Open App.Path & "\PuzzleIniziato" For Input As #1
    Do While Not EOF(1)
    Line Input #1, Text
    List1.AddItem Text
     Loop
     Close #1
     Exit Sub
     End Sub
- e infine la Sub relativa allo scambio con il MouseDown l'ho modificata così:
Private Sub Picture2_MouseDown(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button <> vbLeftButton Then Exit Sub
If MousePointer = 0 And Picture2(Index).Picture = ImageList1.ListImages(Index + 1).Picture Then
Beep
Text1 = Val(Text1) - 1: If Val(Text1) < 0 Then Text1 = 0
List1.AddItem Index + 1
End If
If MousePointer = 0 Then
MouseIcon = Picture2(Index).Picture
tmpTag = Picture2(Index).Tag 'Al
MousePointer = 99
Picture2(Index) = Picture3.Picture
I = Index
If Picture2(Index).Picture = ImageList1.ListImages(Index + 1).Picture Then
Beep
Text1 = Val(Text1) + 1
End If
ElseIf MousePointer = 99 Then
Picture2(I) = Picture2(Index)
Picture2(Index) = MouseIcon
MousePointer = 0
If Picture2(Index).Picture = ImageList1.ListImages(Index + 1).Picture Then
Beep
Text1 = Val(Text1) + 1
List1.AddItem Index + 1
End If
'**
Else
Picture2(I) = Picture2(Index) 'Al
Picture2(I).Tag = Picture2(Index).Tag 'Al
Picture2(Index) = MouseIcon 'Al
Picture2(Index).Tag = tmpTag 'Al
'**
End If
PuzzleCompletato
End Sub

Tuttavia la fase di salvataggio dei dati non va ancora bene perchè al richiamo si presentano sempre le tessere in modo casuale. Mi aiuti ancora?
aaa