Dzisiaj zrobimy sobie bardzo przyjemną grę logiczną. Polega ona na klikaniu w pewien wyświetlany wzór kolorów. Gra po ukończeniu będzie wyglądać jak na filmie, film zawiera również prezentację jak rozmieścić wszystkie elementy gry na formię.
Będzie miała nieograniczoną liczbę poziomów, rosnący stopień trudności i sumującą się liczbę punktów. Grę będzie można samemu bez problemów modyfikować, postaram się wszystko wyjaśnić w biegu tworzenia gry 🙂 .
Zaczniemy od dodania zmiennych w Form1 wpisujemy:
Public Class Form1
''Dane publiczne
Public interval As Integer = 500 'Odpowiada za szybkość pojawiania i znikania kolorów
Public Wpoziomu As Integer = 1 'Startowa wartość poziomu
''Dane lokalne
Dim zycia As Integer = 3 'zmienna przechowująca ilość żyć
Dim Wpunkty As Integer = 0 'zmienna przechowująca ilość punktów
Dim losowaLista As New List(Of Integer) 'lista wylosowanych kolorów
Dim listaUzytkownika As New List(Of Integer) 'lista kolorów użytkownika
Dim randomNum As New Random
Dim iloscRozegranychGier As Integer = 0 'zmienna przechowująca ilość rozegranych partii
Dim enableMouseClickPanel As Boolean = False 'kontroler, będzie blokował możliwość klikania
' na kwadraty podczas prezentowania sekwencji
(...)
Teraz dodamy sobie konfigurację w momencie załadowania formy, w tym celu klikamy dwukrotnie na naszą formę dodając Form1_Load wpisujemy w nim
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Panel1.BackColor = Color.FromArgb(25, Color.Blue)
Panel2.BackColor = Color.FromArgb(25, Color.Red)
Panel3.BackColor = Color.FromArgb(25, Color.Black)
Panel4.BackColor = Color.FromArgb(25, Color.Yellow)
Panel5.BackColor = Color.FromArgb(25, Color.Brown)
Panel6.BackColor = Color.FromArgb(25, Color.Indigo)
Panel7.BackColor = Color.FromArgb(25, Color.DeepPink)
Panel8.BackColor = Color.FromArgb(25, Color.Cyan)
Panel9.BackColor = Color.FromArgb(25, Color.Fuchsia)
Panel10.BackColor = Color.FromArgb(25, Color.Teal)
Panel11.BackColor = Color.FromArgb(25, Color.Lime)
Panel12.BackColor = Color.FromArgb(25, Color.OrangeRed)
End Sub
Każdy Panel ma swój oddzielny kolor, każdy kolor ma zmniejszoną wartość wizualizacji, przyjmuje ona wartość z przedziału od 0-255 im jest mniejsza tym kolor jest bardziej przezroczysty. Po uruchomieniu nasza forma będzie wyglądała tak jak na obrazku:
Poprzez zmianę wartości z 25 na 255 będziemy wyostrzać pewną sekwencje kolorów którą użytkownik będzie musiał powtórzyć. Sekwencja będzie wybierana losowa w zależności od aktualnego poziomu.
Private Sub losujKolory(ByVal poziom As Integer)
'czyści listę przed każdym losowaniem
losowaLista.Clear()
'ta zmienna i sekwencja na niej oparta uniemożliwi wylosowanie dwóch takich samych liczb pod rząd
Dim liczbawczesniejsza As Integer = 0
'Pętla losująca
For i As Integer = 0 To poziom
Dim wylosowanaliczba As Integer = 0
'losuje liczbę z przedziału od 1 do 12
wylosowanaliczba = randomNum.Next(1, 12)
'sprawdza czy liczba była już wcześniej wylosowana
If wylosowanaliczba = liczbawczesniejsza Then
'jeśli została wylosowana, wtedy losowanie będzie powtórzone do momętu
' wylosowania innej liczby niż ta wylosowana wcześniej
Do Until Not (wylosowanaliczba = liczbawczesniejsza)
wylosowanaliczba = randomNum.Next(1, 12)
Loop
End If
losowaLista.Add(wylosowanaliczba)
liczbawczesniejsza = wylosowanaliczba
Next
End Sub
Do opóźnienia danego efektu służy metoda: Await Task.Delay(„wartość opóźnienia”). po dodaniu tej metody nasz program będzie kontynuował swoje działanie po przekroczeniu tego czasu. Czyli zrobimy tak, najpierw podświetlimy sobie jeden kwadracik następnie poczekamy jakiś czas, (ta wartość będzie zależna od poziomu trudności) zgasimy go i zapalimy kolejny. Najpierw zrobimy sobie dwie metody które będą gasić i świecić nam kwadraty:
' zapala kolor
Private Async Function podswietlenieKoloru(ByVal numerKoloru As Integer) As Task
Select Case numerKoloru
Case 1
Panel1.BackColor = Color.FromArgb(255, Color.Blue)
Case 2
Panel2.BackColor = Color.FromArgb(255, Color.Red)
Case 3
Panel3.BackColor = Color.FromArgb(255, Color.Black)
Case 4
Panel4.BackColor = Color.FromArgb(255, Color.Yellow)
Case 5
Panel5.BackColor = Color.FromArgb(255, Color.Brown)
Case 6
Panel6.BackColor = Color.FromArgb(255, Color.Indigo)
Case 7
Panel7.BackColor = Color.FromArgb(255, Color.DeepPink)
Case 8
Panel8.BackColor = Color.FromArgb(255, Color.Cyan)
Case 9
Panel9.BackColor = Color.FromArgb(255, Color.Fuchsia)
Case 10
Panel10.BackColor = Color.FromArgb(255, Color.Teal)
Case 11
Panel11.BackColor = Color.FromArgb(255, Color.Lime)
Case 12
Panel12.BackColor = Color.FromArgb(255, Color.OrangeRed)
End Select
''opóźnienie
Await Task.Delay(interval)
'gasi kolor
zgaszenieKoloru(numerKoloru)
End Function
' gasi kolor
Private Sub zgaszenieKoloru(ByVal numerKoloru As Integer)
Select Case numerKoloru
Case 1
Panel1.BackColor = Color.FromArgb(25, Color.Blue)
Case 2
Panel2.BackColor = Color.FromArgb(25, Color.Red)
Case 3
Panel3.BackColor = Color.FromArgb(25, Color.Black)
Case 4
Panel4.BackColor = Color.FromArgb(25, Color.Yellow)
Case 5
Panel5.BackColor = Color.FromArgb(25, Color.Brown)
Case 6
Panel6.BackColor = Color.FromArgb(25, Color.Indigo)
Case 7
Panel7.BackColor = Color.FromArgb(25, Color.DeepPink)
Case 8
Panel8.BackColor = Color.FromArgb(25, Color.Cyan)
Case 9
Panel9.BackColor = Color.FromArgb(25, Color.Fuchsia)
Case 10
Panel10.BackColor = Color.FromArgb(25, Color.Teal)
Case 11
Panel11.BackColor = Color.FromArgb(25, Color.Lime)
Case 12
Panel12.BackColor = Color.FromArgb(25, Color.OrangeRed)
End Select
End Sub
Teraz dodajemy metodę która według wylosowanego wcześniej wzoru będzie sekwencyjnie zapalać kolorki:
Private Async Function pokazkolory() As Task
For i As Integer = 0 To Wpoziomu
Await podswietlenieKoloru(losowaLista(i))
Next
enableMouseClickPanel = True
End Function
Jest to bardzo prosta metoda, a główne jej elementy to oczywiście podswietlenieKoloru() i zgaszenieKoloru(). Tworzymy sobie odwołanie do przycisku „Start” zobaczymy czy wszystko działa jak trzeba.
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'blokuje możliwość przyciskania kwadracików w momęcie wyświetlania sekwencji
enableMouseClickPanel = False
'ustawia ilość żyć
zycia = 3
'wyłącza działanie przycisku "start"
Button1.Enabled = False
'zeruje punkty
Wpunkty = 0
punkty.Text = Wpunkty.ToString
'zeruje ilosc rozgrywek
iloscRozegranychGier = 0
'pokazuje serca, jeśli byly niewidoczne
serce1.Visible = True
serce2.Visible = True
serce3.Visible = True
poziom.Text = Wpoziomu.ToString
'wyświetla poziom trudności
PoziomTrudności()
'losuje kolory
losujKolory(Wpoziomu)
'pokazuje kolory
Await pokazkolory()
End Sub
Pozbywając się chwilowo nieaktywnych metod (podkreślonych na czerwono) przyciśnięcie przycisku „Start” powinno spowodować pojawienie się sekwencji kolorów. Do każdego Panelu dodajemy zdarzenie „MouseClick” następnie zmieniamy je w następujący sposób:
Private Async Sub Panel1_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel1.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(1)
Await sprawdzLiczbe(1)
End If
End Sub
Private Async Sub Panel2_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel2.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(2)
Await sprawdzLiczbe(2)
End If
End Sub
Private Async Sub Panel3_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel3.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(3)
Await sprawdzLiczbe(3)
End If
End Sub
Private Async Sub Panel4_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel4.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(4)
Await sprawdzLiczbe(4)
End If
End Sub
Private Async Sub Panel5_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel5.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(5)
Await sprawdzLiczbe(5)
End If
End Sub
Private Async Sub Panel6_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel6.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(6)
Await sprawdzLiczbe(6)
End If
End Sub
Private Async Sub Panel7_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel7.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(7)
Await sprawdzLiczbe(7)
End If
End Sub
Private Async Sub Panel8_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel8.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(8)
Await sprawdzLiczbe(8)
End If
End Sub
Private Async Sub Panel9_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel9.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(9)
Await sprawdzLiczbe(9)
End If
End Sub
Private Async Sub Panel10_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel10.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(10)
Await sprawdzLiczbe(10)
End If
End Sub
Private Async Sub Panel11_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel11.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(11)
Await sprawdzLiczbe(11)
End If
End Sub
Private Async Sub Panel12_MouseClick(sender As Object, e As MouseEventArgs) Handles Panel12.MouseClick
If enableMouseClickPanel = True Then
Await podswietlenieKoloru(12)
Await sprawdzLiczbe(12)
End If
End Sub
To daje nam możliwość klikania na każdy panel i sprawdzania czy trafiliśmy odpowiednie kolory. Sercem naszego programu będzie metoda sprawdzLiczbe() która po wprowadzeniu wartości z wybranego panelu będzie sprawdzał czy wartość ta znajduje się w wylosowanych liczbach.
Private Async Function sprawdzLiczbe(ByVal liczba As Integer) As Task
'blokuje kwadraty
enableMouseClickPanel = False
'dodaje odpowiednią liczbę z kwadratu
listaUzytkownika.Add(liczba)
'sprawdza liczbę
If losowaLista(listaUzytkownika.Count - 1) = liczba Then
'Jeśli liczba jest poprawna dostaniemy punkty, odpowiednio większe w zależności od poziomu
Wpunkty += Wpoziomu
'odblokowuje kwadraty
enableMouseClickPanel = True
Else
'Jeśli wybrana liczba nie jest taka jak wylosowana wtedy życie zostaje odjęte
zycia -= 1
'metoda usuwa serduszko
odejmijserce()
If zycia <= 0 Then
' Jeśli gracz nie ma już życia gra jest kończona
MsgBox("Przegrałeś, twój wynik to: " + Wpunkty.ToString)
Button1.Enabled = True
listaUzytkownika.Clear()
losowaLista.Clear()
Exit Function
Else
'jeśli gracz posiada życie, pokazany zostanie komunikat a losowanie kolorów odbędzie się na nowo
Dim rezultat As DialogResult
rezultat = MessageBox.Show("Popelniles bląd zostały ci " + zycia.ToString + " życia.", "Błąd", MessageBoxButtons.OK)
If rezultat = Windows.Forms.DialogResult.OK Then
Await Task.Delay(500)
listaUzytkownika.Clear()
losowaLista.Clear()
losujKolory(Wpoziomu)
Await pokazkolory()
enableMouseClickPanel = True
End If
End If
End If
'Jeśli wszystkie wartości z sekwencji wylosowanych liczb zostaną wprowadzone wtedy
If listaUzytkownika.Count = losowaLista.Count Then
'listy są czyszczone
Await Task.Delay(500)
listaUzytkownika.Clear()
losowaLista.Clear()
'losowanie odbywa się na nowo
losujKolory(Wpoziomu)
Await pokazkolory()
'dodawane są wartości
iloscRozegranychGier += 1
Wpoziomu = Math.Round(Math.Sqrt(iloscRozegranychGier) + 500 / interval, 0)
poziom.Text = Wpoziomu.ToString
enableMouseClickPanel = True
End If
punkty.Text = Wpunkty.ToString
End Function
Dodatkowe wartości i metody dodajemy w kodzie poniżej, wyświetlają one poziom trudności, odejmują serduszko, otwierają ustawienia.
'odejmuje serduszka
Private Sub odejmijserce()
If serce3.Visible = False And serce2.Visible = False And serce1.Visible = True Then
serce1.Visible = False
End If
If serce3.Visible = False And serce2.Visible = True And serce1.Visible = True Then
serce2.Visible = False
End If
If serce3.Visible = True And serce2.Visible = True And serce1.Visible = True Then
serce3.Visible = False
End If
End Sub
'otwiera formę ustawień
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Form2.Show()
End Sub
'Czyści wartości
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Button1.Enabled = True
listaUzytkownika.Clear()
losowaLista.Clear()
enableMouseClickPanel = False
End Sub
'Wyświetla poziom trudności
Public Sub PoziomTrudności()
If interval <= 100 Then
StTrudnosci.Text = "Legendarny"
ElseIf interval > 100 And interval <= 200 Then
StTrudnosci.Text = "Bardzo trudny"
ElseIf interval > 200 And interval <= 300 Then
StTrudnosci.Text = "Trudny"
ElseIf interval > 300 And interval <= 400 Then
StTrudnosci.Text = "Średni"
ElseIf interval > 400 And interval <= 500 Then
StTrudnosci.Text = "Łatwy"
ElseIf interval > 500 Then
StTrudnosci.Text = "Bardzo łatwy"
End If
End Sub
Dwie wartości ustawiliśmy jako publiczne, dzięki temu możemy bez problemu zmieniać ich wartości w innych oknach. Po otworzeniu drugiej formy wypełniamy ją kodem:
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
NumericUpDown1.Value = Form1.interval
NumericUpDown2.Value = Form1.Wpoziomu
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
Form1.interval = NumericUpDown1.Value
Form1.Wpoziomu = NumericUpDown2.Value
Me.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Me.Close()
End Sub
End Class
To pozwoli zmienić nam szybkość gry i ilość wyświetlanych kolorów. 
Projekt dostępny do pobrania tutaj: Gra_w_kolory


