|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: May 2009
Messaggi: 147
|
[VB.NET] Generare numeri casuali a scorrimento
Salve a tutti!!vorrei sapere se in visual basic.net è possibile creare ,ad esempio in una textobox, un effetto di scorrimento di numeri casuali dall'alto verso il basso, stile slot machine!grazie a tutti!attendo risposta!
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Feb 2003
Città: Stockholm (SE)
Messaggi: 1343
|
divide et impera!
scomponi il problema in sottoproblemi meno complessi: 1) generare numeri casuali 2) realizzare effetto slot machine |
|
|
|
|
|
#3 |
|
Member
Iscritto dal: May 2009
Messaggi: 147
|
ma l'effetto slot come si realizza??
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Puoi usare le GDI+, oppure con un po' di "furbizia" alcuni controlli standard, come picturebox e labels ( giocando sulla disposizione in primo piano e sullo sfondo... ). In più, sicuramente uno o più Timers, per regolare l'effetto di movimento ( con accelerazioni / decelerazioni )... Insomma, una bella divertita.
|
|
|
|
|
|
#5 |
|
Member
Iscritto dal: May 2009
Messaggi: 147
|
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Comunque non è una cosa certo "elementare". Che tu sia un neofita o sviluppatore senior, per realizzarla bisogna prima pensarla bene, oltretutto possono esserci molte strade possibili, non è una procedura "guidata", come inserire un record in un DB... |
|
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Ce la si può fare con : 1 Panel / N Labels ( o meglio controlli personalizzati ) / 1 Timer per "ruota"... Perciò a monte il mio precedente consiglio su GDI+ ( che è cmq sempre una valida alternativa ) o gestione dello ZOrder ( porta in primo piano, porta in secondo piano )... Ultima modifica di MarcoGG : 22-06-2009 alle 21:23. |
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Riporto in alto questa discussione, perchè si da il caso che abbia appena realizzato per altri scopi qualcosa di utile e "divertente". Almeno lo è per me.
Un mio generatore un po' avanzato di numeri interi casuali, con un funzionamento "accattivante", stile Slot-Machine, o Video-Poker se preferite : 1. Descrizione : Il progetto è di tipo Windows Forms, e le Classi essenziali alla compilazione sono le seguenti : - Casella.vb : Controllo UserControl ( Controllo Utente ). - Ruota.vb : Controllo UserControl ( Controllo Utente ). - ModuloPublics.vb : Modulo. - FormMain.vb : Form ( Form di avvio ). Ho incluso nelle immagini che seguono le proprietà che è utile impostare a Design affinchè il progetto possa essere riprodotto fedelmente. 2. Casella.vb : E' l'elemento base. Ogni Ruota può contenere N Oggetti Casella. Nel presente progetto ho limitato N in modo opportuno : - N minimo = 2 ( per ovvi motivi ). - N massimo = 10 ( da 0 a 9 ). La struttura di Casella è semplice : - lbl_valore : Label. Codice per Casella.vb : Codice:
Public Class Casella
'Dimensioni Fisse
Private m_w As Integer = 200
Private m_h As Integer = 200
Private m_valore As Integer
Public Property valore() As Integer
Get
Return m_valore
End Get
Set(ByVal value As Integer)
m_valore = value
Me.lbl_valore.Text = m_valore
End Set
End Property
Protected Overrides Sub SetBoundsCore(ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer, ByVal specified As System.Windows.Forms.BoundsSpecified)
MyBase.SetBoundsCore(x, y, m_w, m_h, specified)
End Sub
End Class
La Ruota è la Classe centrale del progetto. Provvede a caricare le caselle, a farle girare e a generare i valori casuali. Così come per Casella.vb, le dimensioni di Ruota non possono essere decise a casaccio, perciò per semplicità anche in questo caso sono bloccate. In teoria sarebbe stato più corretto includere Casella in Ruota, come Inner Class ( o Nested Class... ), dal momento che Casella non ha alcuno scopo senza Ruota, ecc... ecc... Perciò lo scrivo chiaramente una volta sola : ho volutamente evitato di spingermi troppo in là nell'ottimizzazione, allo scopo di rendere il codice più separato e lineare, e quindi comprensibile anche a chi non ha grande dimestichezza con l'approccio OOP di VB.NET. Nella prossima immagine descrivo l'aspetto generale di una FormMain tipica, con 3 Ruote. Nell'immagine ho incluso la descrizione dei componenti e proprietà essenziali di Ruota.vb. - lbl_numruota : Label. - nup_numcaselle : NumericUpDown. - cmb_velocitàruota : ComboBox. - pnl_ruota : Panel. - cmd_start : Button. e tmr_ruota, il controllo Timer da aggiungere a Ruota.vb in Design. ( Ammetto di avere un uso abbastanza personale della cosiddetta "notazione ungherese", ma sono abitudini dure da sradicare... Codice per Ruota.vb : Codice:
Public Class Ruota
'Membri Interni N.A.
Private m_w As Integer = 240 'Dimensioni Fisse
Private m_h As Integer = 240 'Dimensioni Fisse
Private m_tmrTicks As Integer = 0
Private m_speedMin As Integer = 80
Private m_speedMax As Integer = 120
Private m_speed As Integer = 0
Private m_scarto As Integer = 0
'Membri Interni Property
Private m_numCaselleRuota As Integer = 10
Private m_inGiocoRuota As Boolean = False
Private m_esitoRuota As Integer = 0
Private m_numRuota As Integer = 0
Private m_velocitàRuota As Integer = 20
Public Property NumCaselleRuota() As Integer
Get
Return m_numCaselleRuota
End Get
Set(ByVal value As Integer)
If value < 2 Then
m_numCaselleRuota = 2
Else
m_numCaselleRuota = value
End If
Me.ResetRuota()
End Set
End Property
Public ReadOnly Property InGiocoRuota() As Boolean
Get
Return m_inGiocoRuota
End Get
End Property
Public ReadOnly Property EsitoRuota() As Integer
Get
Return m_esitoRuota
End Get
End Property
Public Property NumRuota() As Integer
Get
Return m_numRuota
End Get
Set(ByVal value As Integer)
m_numRuota = value
Me.lbl_numruota.Text = m_numRuota
End Set
End Property
Public Property VelocitàRuota() As Integer
Get
Return m_velocitàRuota
End Get
Set(ByVal value As Integer)
If value <= 0 Then
m_velocitàRuota = 20
Else
m_velocitàRuota = value
End If
Me.tmr_ruota.Interval = m_velocitàRuota
End Set
End Property
Protected Overrides Sub SetBoundsCore(ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer, ByVal specified As System.Windows.Forms.BoundsSpecified)
MyBase.SetBoundsCore(x, y, m_w, m_h, specified)
End Sub
Private Sub ResetRuota()
Me.pnl_ruota.BackColor = Color.Black
Me.pnl_ruota.Controls.Clear()
For i As Integer = 1 To m_numCaselleRuota
Dim C As New Casella
C.valore = i - 1
Me.pnl_ruota.Controls.Add(C)
C.Left = 10
C.Top = (1 - i) * C.Height
Next
End Sub
Public Sub Start()
'Normalizzazione valori per SeedX Random
Dim nr As Integer = m_numRuota * 99
Dim ttcks As Integer = Convert.ToInt32(m_tmrTicks.ToString.PadRight(3, "9"))
Dim er As Integer = m_esitoRuota * 99
Dim mox As Integer = Cursor.Position.X
Dim moy As Integer = Cursor.Position.Y
Dim sxs As Integer = nr + er + ttcks + mox + moy
m_speed = RandomizzaIntero(m_speedMin, m_speedMax, sxs)
m_inGiocoRuota = True
Me.pnl_ruota.BackColor = Color.Black
Me.tmr_ruota.Enabled = True
End Sub
Private Sub tmr_ruota_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmr_ruota.Tick
If m_tmrTicks = 999 Then
m_tmrTicks = 1
Else
m_tmrTicks += 1
End If
Dim sxt As Integer = Convert.ToInt32(m_tmrTicks.ToString.PadRight(3, "9"))
For Each C As Casella In Me.pnl_ruota.Controls
C.Top = C.Top + m_speed
Next
For Each C As Casella In Me.pnl_ruota.Controls
If C.Top > C.Height Then
C.Top = C.Top - m_numCaselleRuota * C.Height
Try
'Aggiungere qui un suono per slot casella
My.Computer.Audio.Play(suonoSlot, AudioPlayMode.Background)
Catch ex As Exception
End Try
End If
Next
If m_inGiocoRuota = True Then
m_speed -= RandomizzaIntero(0, 1, sxt)
Else
m_scarto -= 1
If m_scarto = 0 Then
Me.tmr_ruota.Enabled = False
End If
End If
If m_speed <= 0 And m_inGiocoRuota = True Then
m_scarto = Integer.MaxValue
m_inGiocoRuota = False
Me.pnl_ruota.BackColor = Color.LimeGreen
For Each C As Casella In Me.pnl_ruota.Controls
If Math.Abs(C.Top) < m_scarto Then m_scarto = Math.Abs(C.Top)
Next
For Each C As Casella In Me.pnl_ruota.Controls
If Math.Abs(C.Top) = m_scarto Then
m_esitoRuota = C.valore
If C.Top > 0 Then
m_speed = -1
ElseIf C.Top < 0 Then
m_speed = 1
Else 'C.Top = 0
m_speed = 0
End If
Exit For
End If
Next
End If
End Sub
End Class
Codice:
Try
'Aggiungere qui un suono per slot casella
My.Computer.Audio.Play(suonoSlot, AudioPlayMode.Background)
Catch ex As Exception
End Try
4. FormMain.vb : Oltre ai controlli già visti è necessario aggiungere al Design di FormMain un controllo Timer "tmr_check", con un Interval sui 400-500 msec. Come suggerisce il nome tmr_check controlla tutte le ruote in azione su FormMain... Codice per FormMain : Codice:
'**************************************************
'GENERATORE RANDOM SLOT - MarcoGG - 2010 **********
'**************************************************
Public Class FormMain
Private Sub FormMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
cmb_velocitàruota.Text = cmb_velocitàruota.Items(0)
For Each R As Control In Me.Controls
If TypeOf R Is Ruota Then ruote.Add(R)
Next
For Each R As Ruota In ruote
R.NumCaselleRuota = nup_numcaselle.Value
R.NumRuota = ruote.IndexOf(R) + 1
Next
End Sub
Private Sub cmd_start_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmd_start.Click
msg = New System.Text.StringBuilder
esitoReport = New System.Text.StringBuilder
For Each R As Ruota In ruote
R.Start()
Next
cmd_start.Enabled = False
nup_numcaselle.Enabled = False
cmb_velocitàruota.Enabled = False
tmr_check.Enabled = True
End Sub
Private Sub tmr_check_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmr_check.Tick
For Each R As Ruota In ruote
If R.InGiocoRuota = True Then Exit Sub
Next
tmr_check.Enabled = False
For Each R As Ruota In ruote
msg.Append("RUOTA " & R.NumRuota & " : " & R.EsitoRuota & vbCrLf)
esitoReport.Append(R.EsitoRuota.ToString)
Next
MsgBox(msg.ToString, MsgBoxStyle.Information, "OK")
CreaAccodaReport(esitoReport.ToString)
cmd_start.Enabled = True
nup_numcaselle.Enabled = True
cmb_velocitàruota.Enabled = True
End Sub
Private Sub cmb_velocitàruota_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmb_velocitàruota.SelectedIndexChanged
'0.Normale - Risultato in circa 9 sec.
'1.Veloce - Risultato in circa 4 sec.
Dim V As Integer = 20 - cmb_velocitàruota.SelectedIndex * 10
For Each R As Ruota In ruote
R.VelocitàRuota = V
Next
End Sub
Private Sub nup_numcaselle_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles nup_numcaselle.ValueChanged
For Each R As Ruota In ruote
R.NumCaselleRuota = nup_numcaselle.Value
Next
End Sub
End Class
Contiene dichiarazioni di utilità generale a livello di Progetto. Codice per ModuloPublics.vb : Codice:
Module ModuloPublics
Public percorso As String = Application.StartupPath & "\"
Public suonoSlot As String = percorso & "slot.wav"
Public reportFile As String = percorso & "GnrtrRndmSlt_Report.txt"
Public ruote As New List(Of Ruota)
Public msg As System.Text.StringBuilder
Public esitoReport As System.Text.StringBuilder
Public Function RandomizzaIntero(ByVal Min As Integer, ByVal Max As Integer, ByVal seedX As Integer) As Integer
If seedX < 0 Then seedX = -seedX
Dim gen As New System.Random(System.DateTime.Now.Millisecond + seedX)
Return gen.Next(Min, Max + 1)
End Function
Public Sub CreaAccodaReport(ByVal esito As String)
My.Computer.FileSystem.WriteAllText(reportFile, esito & vbCrLf, True)
End Sub
End Module
I ) Una volta create le classi, basta eseguire una compilazione per trovare Ruota tra i controlli WinForms utilizzabili. A questo punto si possono aggiungere tutte le ruote che si desiderano alla propria FormMain ( personalmente ho fatto un test con 16 Ruote senza problemi ). Non è assolutamente necessario aggiungere Ruote da codice. Basta usare il Designer. A tutto il resto pensa il MIO codice. II ) Quando FormMain è pronta... START ! III ) Quando tutte le Ruote avranno fornito il loro esito, apparirà una MsgBox di riepilogo. Come ultima chicca, verrà creato e aggiornato ad ogni Start, un semplice report txt : "GnrtrRndmSlt_Report.txt". IV ) Possibili applicazioni ? L'unico limite è la fantasia ! Ok. Direi che c'è tutto. Spero di aver esposto chiaramente. Provvederò più tardi a fornire in allegato l'exe compilato ( FW3.5 ) nonchè il file audio "slot.wav", per i più pigri... Provatelo e fatemi sapere se vi piace ! CIAO a tutti !
__________________
Contattami su FaceBook --> [ ::: MarcoGG su FaceBook ::: ] Visita il mio Blog --> [ ::: Il Blog di MarcoGG ::: ] |
|
|
|
|
|
#9 |
|
Member
Iscritto dal: Feb 2009
Città: Varese
Messaggi: 205
|
Quote:
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Tra poco posto il compilato + file audio, che lo rende ancora più... Slot !
__________________
Contattami su FaceBook --> [ ::: MarcoGG su FaceBook ::: ] Visita il mio Blog --> [ ::: Il Blog di MarcoGG ::: ] |
|
|
|
|
|
|
#11 |
|
Member
Iscritto dal: May 2009
Messaggi: 147
|
Complimenti!!!
Una curiosità con che versione di visual studio lo compili? |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Eccolo !
L'eseguibile : GeneraNumeriCasualiSlot.zip ATTENZIONE : si tratta in realtà di archivio RAR ! Anche se l'estensione è .zip. Chiedo scusa, ma ho solo WinRar. E lo zip andava oltre il limite dei 24.4 KB. E per oscure ragioni qui non si possono uppare files Rar...
__________________
Contattami su FaceBook --> [ ::: MarcoGG su FaceBook ::: ] Visita il mio Blog --> [ ::: Il Blog di MarcoGG ::: ] |
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
E questo è il file slot.wav ( deve stare nella stessa cartella dell'exe ) : slot.zip Potete sostituirlo con un qualsiasi altro file audio .wav di vostro gradimento, a patto che si chiami "slot.wav" e non sia troppo pesante...
__________________
Contattami su FaceBook --> [ ::: MarcoGG su FaceBook ::: ] Visita il mio Blog --> [ ::: Il Blog di MarcoGG ::: ] |
|
|
|
|
|
|
#14 | |
|
Member
Iscritto dal: May 2009
Messaggi: 147
|
Quote:
ottimo lavoro!! |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 08:07.




















