Oppure

Loading
12/04/21 11:58
Sal47
Buongiorno, ho iniziato a studiarmi il codice che mi hai postato.
Ti dico subito che prima che io scriva istruzioni simili ci vorranno secoli, forse.
Si, ho provato a modificare le variabili locali come indicato e ottengo non 4
ma 2 righe, le distanze tra carta e carta sono variate e in effetti non ci sono
immagini a sufficienza; ho anche visto le carte in ImageList1.

Non capisco cosa devo fare in merito a quanto mi indichi al 3° cpv. del tuo
ultimo post:
... inserisci il codice tra
 e 
, ...

Devo forse inserire tutto il codice che mi hai postato nel mio di codice ?

Da come interpreto, ora potrei inserire il tuo codice in quello fatto da me
in modo che risultino inizialmente tutte le carte, 36 nelle 4 righe e 4 in basso
da girare una per volta, opportunamente mischiate con le mie istruzioni e poi coperte
utilizzando per tutte l' ID = 0.
Poi, dopo averle girate una per volta (con ID +=1), dovrei movimentarle
con le Sub PB_OnMouseDown e PB_OnMouseMove e infine utilizzando il
nome della carta che appare nella barra del titolo far aumentare automa-
ticamente di 1 il numero di carte posizionate.

Se è così (e non ne sono sicuro) ci provo ma dubito di riuscirci senza ulteriori aiuti.
In ogni caso ti ringrazio.
Ultima modifica effettuata da Sal47 12/04/21 12:02
aaa
12/04/21 16:25
Carlo
Postato originariamente da Sal47:

Buongiorno, ho iniziato a studiarmi il codice che mi hai postato.
Ti dico subito che prima che io scriva istruzioni simili ci vorranno secoli, forse.
Si, ho provato a modificare le variabili locali come indicato e ottengo non 4
ma 2 righe, le distanze tra carta e carta sono variate e in effetti non ci sono
immagini a sufficienza; ho anche visto le carte in ImageList1.


Non ci vorranno secoli, perché è una semplificazione di quello che fai tu.
Mi dovresti dire cosa non capisci o non sai, in modo che ti do degli aiuti mirati.

Postato originariamente da Sal47:
Non capisco cosa devo fare in merito a quanto mi indichi al 3° cpv. del tuo
ultimo post:
... inserisci il codice tra
 e 
, ...
Devo forse inserire tutto il codice che mi hai postato nel mio di codice ?

intendo di postare la porzione di codice che non capisci usando il code, che come vedi qui sopra con i tag code si attiva la formattazione per mostrare un codice invece del messaggio.

Postato originariamente da Sal47:
Da come interpreto, ora potrei inserire il tuo codice in quello fatto da me
in modo che risultino inizialmente tutte le carte, 36 nelle 4 righe e 4 in basso
da girare una per volta, opportunamente mischiate con le mie istruzioni e poi coperte
utilizzando per tutte l' ID = 0.
Poi, dopo averle girate una per volta (con ID +=1), dovrei movimentarle
con le Sub PB_OnMouseDown e PB_OnMouseMove e infine utilizzando il
nome della carta che appare nella barra del titolo far aumentare automa-
ticamente di 1 il numero di carte posizionate.

Se è così (e non ne sono sicuro) ci provo ma dubito di riuscirci senza ulteriori aiuti.
In ogni caso ti ringrazio.


È così, ti consiglio di parcheggiare il tuo codice, e di modificarlo quando avrai compreso le 4 o 5 istruzioni o logica che ora ti sfuggono...

Per esempio, se nel tuo codice vuoi inserire l'evento MouseUp, lo devi fare per tutte e 40 le picture box e scrivere il relativo codice 40 volte.
Ti posto un codice che ti mostra che invece con sole 10 righe in più si può gestire l'evento MouseUp, determinare la posizione della carta, determinare se è stata spostata nel posto giusto e scambiarla di posto.

Nel progetto allegato ho aggiunto il mescolamento delle carte, il conteggio di quante sono ordinate e la possibilità di riordinare le carte mescolate spostandole nella giusta posizione con il mouse.

Non ho volutamente scritto il codice che permette di giocare al solitario napoletano, perché ritengo che piace scriverlo a te, ma con gli esempi che ti posto cerco di evitarti di infilarti in un vicolo cieco o ingarbugliato.
Ultima modifica effettuata da Carlo 12/04/21 20:17
in programmazione tutto è permesso
13/04/21 15:53
Sal47
Ciao, ho scaricato il Carte2 e letto i tuoi commenti.

Ho capito che con Form1_Load vengono memorizzate le corrette posizioni finali delle 40 carte
(1^ riga denari, 2^ coppe, 3^ bastoni e 4^ spade). Dopo mescolo le carte e sposto una
x volta le carte e se (PB_OnMouseUp) vengono rimesse in posizione giusta (+/- margine)
(es. 3 coppe nella 3^ colonna della 2^ riga) lo spostamento va a buon fine altrimenti
il 3 di coppe ritorna automaticamente nella posizione iniziale e ListBox1.backcolor>red.
OK per il mescolamento delle carte e per la Verifica.

Ora però, a carte mischiate, devo farle apparire coperte e con 4 righe da 9 e 4 carte in basso
e procedere così nel solitario.

Sto provando a digerire il tuo codice. Ho bisogno di tempo.
Tra le tante istruzion/Sub riportate nel tuo codice vorrei capire in particolare:
- come si fa ad ottenere una istruzione valida ad es. per ciascuno dei 40 controlli tipo Label o Button
del mio caso senza ripetere l'istruzione stessa 40 volte come hai visto che ho fatto nel mio codice.
Da una dritta trovata on line mi sembrava che con istruzioni come quelle sotto
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click, Label2.Click,...,
Label3.Click, ... , Label40.Ckick
........
End Sub
e idem per le Sub tipo
Public Sub PictureBox1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown,
PictureBox2.MouseDown,..., PictureBox40.MouseDown,
.........
End Sub
la cosa dovesse funzionare ma non è così e vedo che tu utilizzi "Sender" e una sola istruzione

- anche l'utilizzo di PB(ID).Tag = inf ' NET TAG TUTTI I PARAMETRI DI INTERESSE, ...

Ma sto abusando anche troppo della tua pazienza e disponibilità.
Proverò ad andare avanti da solo (si fa per dire!) con il grosso aiuto ricevuto da te finora.
Spero di farti sapere qualche progresso.
Grazie e saluti.
aaa
13/04/21 18:15
Carlo
Postato originariamente da Sal47:

Ciao, ho scaricato il Carte2 e letto i tuoi commenti.

Ho capito che con Form1_Load vengono memorizzate le corrette posizioni finali delle 40 carte
(1^ riga denari, 2^ coppe, 3^ bastoni e 4^ spade). Dopo mescolo le carte e sposto una
x volta le carte e se (PB_OnMouseUp) vengono rimesse in posizione giusta (+/- margine)
(es. 3 coppe nella 3^ colonna della 2^ riga) lo spostamento va a buon fine altrimenti
il 3 di coppe ritorna automaticamente nella posizione iniziale e ListBox1.backcolor>red.
OK per il mescolamento delle carte e per la Verifica.

Bene :k:
Postato originariamente da Sal47:
Ora però, a carte mischiate, devo farle apparire coperte e con 4 righe da 9 e 4 carte in basso
e procedere così nel solitario.

Esatto, è il tuo programma e con le info a disposizione dovresti riuscire a farlo appena avrai digerito l'esempio.

Postato originariamente da Sal47:
Sto provando a digerire il tuo codice. Ho bisogno di tempo.
Tra le tante istruzion/Sub riportate nel tuo codice vorrei capire in particolare:
- come si fa ad ottenere una istruzione valida ad es. per ciascuno dei 40 controlli tipo Label o Button
del mio caso senza ripetere l'istruzione stessa 40 volte come hai visto che ho fatto nel mio codice.
Da una dritta trovata on line mi sembrava che con istruzioni come quelle sotto
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click, Label2.Click,...,
Label3.Click, ... , Label40.Ckick
........
End Sub
e idem per le Sub tipo
Public Sub PictureBox1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown,
PictureBox2.MouseDown,..., PictureBox40.MouseDown,
.........
End Sub

E' un'altro sistema, ma comunque non adatto per 40 PictureBox con tre eventi...
Si può fare anche con Linq e non solo...

Postato originariamente da Sal47:
la cosa dovesse funzionare ma non è così e vedo che tu utilizzi "Sender" e una sola istruzione


Il metodo che ti ho proposto è il più adatto per scrivere un codice compatto per il tipo di programma che vuoi fare.
Stai programmando e sai che nelle variabili si possono inserire dei valori, dovresti anche sapere che ci sono gli Array (matrici), una matrice è una variabile con un indice:
Dim Matrice(3) as integer
Matrice(0) = 20
Matrice(1) = 32
Matrice(2) = 54
Matrice(3) = 99

l'indice è un numero e permette di esplorare tutti i valori della matrice usando i cicli for, ma non solo, l'indice può essere calcolato per raggiungere un valore con una logica matematica... Facile da capire e sicuramente lo sai.

Quello che potrebbe esserti sfuggito è che in VB.Net le matrici possono essere dichiarate per contenere qualsiasi oggetto, non solo numeri e lettere.

Nell'esempio che ti ho postato, ho dichiarato una matrice PB di PictureBox:
 Dim PB(nColonne * nRighe) As PictureBox

cosa significa questo? Che in PB posso inserire 41 PictureBox distinte ognuna dal suo indice.
PB(1) (che contiene l'asso di denari) ha tutte le proprietà che hai gia usato in progettazione, quando hai inserito le PictureBox a mano una per una.
Dopo questa spiegazione dovrebbe esserti facile capire il frammento di codice che crea la PictureBox(0) (la carta coperta)
        Option Explicit On

      ' creazione e posizionamento della carta coperta ID = 0
        PB(ID) = New PictureBox ' una nuova picturebox
      ' dimensione picturebox in accordo con le immagini in imagelist
        PB(ID).Size = ImageList1.ImageSize 
      ' nel nome il nome della carta
        PB(ID).Name = System.IO.Path.GetFileNameWithoutExtension(ImageList1.Images.Keys(0)) 
      ' immagine in accordo con l'indice, carta coperta in questo caso
        PB(ID).Image = ImageList1.Images(ID) 
      ' left calcolato e immesso in inf.L
        inf.L = setL + gapL + ImageList1.ImageSize.Width 
      ' top calcolato e immesso in inf.T (in fondo)
        inf.T = setT + (gapT + ImageList1.ImageSize.Height) * (nRighe + 1) 
      ' l'indice, zero per la carta coperta       
        inf.ID = ID 
      ' uso i parametri per posizionare la picturebox
        PB(ID).Top = inf.T 
      ' uso i parametri per posizionare la picturebox
        PB(ID).Left = inf.L 
      ' NEL TAG TUTTI I PARAMETRI DI INTERESSE, servirà per recuperare i dati
        PB(ID).Tag = inf 
      ' al click del mouse viene eseguito il codice in PB_OnMouseDown
        AddHandler PB(ID).MouseDown, AddressOf PB_OnMouseDown 
      ' mentre si muove il mouse viene eseguito il codice in PB_OnMouseMove
        AddHandler PB(ID).MouseMove, AddressOf PB_OnMouseMove
      ' quando si rilascia il mouse viene eseguito il codice in PB_OnMouseUp
        AddHandler PB(ID).MouseUp, AddressOf PB_OnMouseUp
      ' Aggiungo la picturebox creata, nel Form
        Me.Controls.Add(PB(ID)) 

PB(ID) = New PictureBox ' una nuova picturebox
è l'istruzione che crea la Picturebox e la immette all'indice ID, zero per la carta coperta.
Le proprietà: Size, Name, Image, Top, Left ti dovrebbero essere chiare, e ora sai che si possono leggere o scrivere anche da codice, non solo da progettazione.

Postato originariamente da Sal47:
- anche l'utilizzo di PB(ID).Tag = inf ' NET TAG TUTTI I PARAMETRI DI INTERESSE, ...


per PB(ID).Tag forse una spiegazione aggiuntiva è d'obbligo.
Il .Tag è una proprietà comune a tutti gli oggetti, ce l'ha il Form, le textbox , le label insomma tutto comprese le PictureBox. E' molto utile per parcheggiare informazioni utili riferite a quell'oggetto.
Se da progettazione nella PictureBox3 vai nella finestra delle proprietà e alla voce Tag scrivi ciao poi da codice scrivi:
Dim a as String = PictureBox3.Tag.ToString() ' in a trovi ciao

La particolarirà del Tag è che può contenere un oggetto non solo una stringa, un oggetto come detto prima può contenere qualsiasi cosa anche un form intero carico di strumenti.

nel nostro caso, nel Tag di ogni PictureBox ho inserito una Struct (inf). La Struct è composta da tre valori L, T, ID, quello che basta per portare a termine il tuo programma.

l' istruzione AddHandler crea l'evento
Me.Controls.Add(PB(ID)) aggiunge al Form la picturebox appena creata con tutte le proprietà impostate

nel ciclo dove creo le 40 PictureBox:
       ID += 1
        For r = 1 To nRighe
            For c = 1 To nColonne
                PB(ID) = New PictureBox
                PB(ID).Size = ImageList1.ImageSize
                PB(ID).Name = System.IO.Path.GetFileNameWithoutExtension(ImageList1.Images.Keys(ID))
                PB(ID).Image = ImageList1.Images(ID)
                inf.L = setL + (gapL + ImageList1.ImageSize.Width) * c
                inf.T = setT + (gapT + ImageList1.ImageSize.Height) * r
                inf.ID = ID
                PB(ID).Top = inf.T
                PB(ID).Left = inf.L
                PB(ID).Tag = inf
                AddHandler PB(ID).MouseDown, AddressOf PB_OnMouseDown
                AddHandler PB(ID).MouseMove, AddressOf PB_OnMouseMove
                AddHandler PB(ID).MouseUp, AddressOf PB_OnMouseUp
                Me.Controls.Add(PB(ID))
                ID += 1
            Next
        Next

calcolo la coordinata di colonna Left e quella di riga Top con due somme e una moltiplicazione le immetto in inf.L e inf.T insieme a inf.ID e poi nel Tag per poterle recuperare quando serve.

Con questo approcio non mi devo segnare a mano tutte le coordinate delle PictureBox e immetterle in una tabella per confrontarle con la posizione della carta quando si muove per vedere se è in posizione.

Infatti quando creo le coordinate le copio anche nel tag, in modo che ogni volta che clicco la carta so dove deve stare, e confrontando con dove sta, so se sta a posto.

Per il sender credo che hai capito, per esempio nel ciclo for abbiamo attivato 40 eventi MouseDown, significa che se clicco una PictureBox qualsiasi, il codice relativo si attiva e in Object sender mi ritrovo tutta la PictureBox cliccata, la conversione da Object a PictureBox è consigliata anche se VB.Net lo farebbe d'ufficio.
Come hai visto, usando il sender si usa sempre lo stesso codice invece di riscriverlo.

Se ancora non riesci, a carte mischiate a farle apparire coperte e con 4 righe e 9 colonne con 4 carte in basso, fammelo sapere.
Ultima modifica effettuata da Carlo 13/04/21 18:49
in programmazione tutto è permesso
13/04/21 18:52
Sal47
Ciao, grazie delle ulteriori preziose informazioni. Ne farò certamente tesoro (pensa che ho anche acquistato il testo "Visual basic 2019, testo completo per lo sviluppatore";) ma per il mio livello non mi è di nessun aiuto.
Ne ho di materiale da studiare!
Ancora grazie e buona serata.
aaa
14/04/21 7:55
Carlo
Se segui il libro, all'inizio devi eseguire gli esercizi e non è detto che la sequenza proposta sia adatta per sviluppare un gioco di tua invenzione, devi aspettare con pazienza e arrivare alla fine.
Una guida valida la trovi anche qui, sul sito di Pierotofy scritta da Totem: pierotofy.it/pages/guide/Guida_al_Visual_Basic_dotNET/

Per il tuo solitario, hai provato a spostare le carte PB(10), PB(20), PB(30), e PB(40) dopo che sono state create, sotto?
Per coprire le carte, nelle picturebox si possono inserire due immagini, dovresti modificare il codice dove viene caricata la carta da:
  PB(ID).Image = ImageList1.Images(ID)

a
  PB(ID).BackgroundImage = ImageList1.Images(ID)

in modo da avere la proprietà Image libera per inserire il dorso.
Quando vuoi nascondere la carta:
  PB(ID).Image = ImageList1.Images(0)

in BackgroundImage ci resta l'immagine della carta, ma non si vede più perché sarà coperta da Image,
ID è l'indice della carta e se metti l'istruzione dentro a un for, prima di mescolarle, le puoi coprire tutte con un unico ciclo.
Quando vuoi scoprire la carta è sufficiente eliminare Image:
  PB(ID).Image = Nothing ' cancellando image si scopre BackgroundImage

per esempio, dopo che hai coperto tutte le carte con il ciclo for, se nell'evento PB_OnMouseDown, aggiungi l'istruzione:
  p.Image = Nothing 

ogni carta coperta cliccata svelerà la sua immagine.

Se ti serve un esempio chiedi :asd:


Ultima modifica effettuata da Carlo 14/04/21 8:09
in programmazione tutto è permesso
14/04/21 15:23
Sal47
Ciao, ..., solo per dirti che ormai mi sono "incartato" e non ne vengo fuori, e più tento di andare avanti più mi incarto.
Evidentemente sto cercando di ottenere troppo in una volta e quindi, seguendo il tuo consiglio, per ora abbandono il solitario col mio metodo non riuscendo ad incastrare in esso le tue istruzioni.
Mi dedicherò a studiare i metodi che mi hai indicato cercando di applicarli a semplici programmi, anche aiutandomi con la guida di Totem, sperando di riuscire a riprendere piu avanti il solitario.
Ti farò sapere.
Davvero grazie per il supporto datomi.
aaa