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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
' 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:
1 2 3 4 5 6 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
'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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
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