Gra w statki

Zasad tej gry chyba nikomu nie muszę wyjaśniać. W tutorialu zajmiemy się tylko podstawowymi zagadnieniami tej gry, czyli planszą, rozstawianiem statków i strzelaniem. Poniżej macie przykładową grę stworzoną w języku vb.net grywalną zarówno z komputerem, we dwójkę przy jednym komputerze, jak i grę przy użyciu protokołu TCP/IP.

 

Statki wersja 1.1.zip

 

 

 

 

Zaczniemy od przygotowania planszy do gry, będą nam potrzebne następujące elementy:

Rodzaj elementu Nazwa elementu Ustawienia
Form Form1 Name: Form1
Text: Okręty VisualMonsters.cba.pl
Size: 1015; 545
Picturebox gracz1 Name: gracz1
Size: 478; 478
Location: 13;13
BackColor: White
Anchor: Top, Left
Picturebox gracz2 Name: gracz2
Size: 478; 478
Location: 506; 13
BackColor: White
Anchor: Top, Left

 

Do gry użyjemy Pictureboxów, które będziemy blokować w zależności od tego, który aktualnie gracz będzie wykonywał strzał. Podzielimy nasze obszary na pola 10×10. Posłuży nam do tego kod poniżej, który wygenerujemy obiekty Rectangle z określoną pozycją i wielkością. Dla lepszej widoczności dodałem im niepełny kolor czerwony:

Public Class Form1

    Dim PlanszaGlowna As New Bitmap(478, 478)

    Dim StrzelnicaGracz1 As New Bitmap(478, 478)
    Dim StrzelnicaGracz2 As New Bitmap(478, 478)

    Private polaGracza1(,) As Rectangle
    Private polaGracza2(,) As Rectangle
    
    Dim graRozpoczeta As Boolean = False

    Private PolaulozonychokretowGracz1(,) As Boolean
    Private PolaulozonychokretowGracz2(,) As Boolean


    Private Sub initRectangles()

        Dim g As Graphics = Graphics.FromImage(PlanszaGlowna)

        'inicjujemy ponownie nasze tabele
        ReDim polaGracza1(9, 9)
        ReDim polaGracza2(9, 9)

        ReDim PolaulozonychokretowGracz1(9, 9)
        ReDim PolaulozonychokretowGracz2(9, 9)

        Dim kolorPola As New SolidBrush(Color.FromArgb(60, 255, 0, 0))
        'tworzy bitmapę tła zarówno gracza1 jak i gracza2
        For j As Integer = 0 To 9
            For i As Integer = 0 To 9
                polaGracza1(i, j) = New Rectangle(10 + (46 * j), 10 + (46 * i), 41, 41)
                PolaulozonychokretowGracz1(i, j) = False
                polaGracza2(i, j) = New Rectangle(10 + (46 * j), 10 + (46 * i), 41, 41)
                PolaulozonychokretowGracz2(i, j) = False
                g.FillRectangle(kolorPola, polaGracza1(i, j))
            Next
        Next

        'ustawiamy grafikę tła
        gracz1.Image = PlanszaGlowna
        gracz2.Image = PlanszaGlowna
        ' PlanszaZOkretamiGracza1 = PlanszaGlowna.Clone()
        ' PlanszaZOkretamiGracza2 = PlanszaGlowna.Clone()
        g.Dispose()
        Me.Refresh()
    End Sub


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        initRectangles()
    End Sub
End Class

Teraz gdy mamy planszę, na której możemy umieścić nasze statki, przejdziemy do podświetlenia elementu, nad którym znajduje się kursor myszy. Gdy kursor znajdzie się nad naszym panelem, zostanie wychwycony a jego położenie odczytane. Kiedy znajdzie się w określonej pozycji, podświetlimy go. Użyjemy do tego zdarzenia MouseMove zarówno do pierwszego panelu, jak i do drugiego:

    Private Sub gracz1_MouseMove(sender As Object, e As MouseEventArgs) Handles gracz1.MouseMove
        'tworzymy chwilową podglądową bitmapę
        Dim BitmapaPodgladowa As New Bitmap(PlanszaGlowna)
        Dim g As Graphics = Graphics.FromImage(BitmapaPodgladowa)
        'pętla wychwytuje kwadrat nad którym znajduje się kursor myszy
        For j As Integer = 0 To 9
            For i As Integer = 0 To 9
                If (polaGracza1(i, j).Location.X - 2 <= e.X And (polaGracza1(i, j).Location.X +
                         polaGracza1(i, j).Width + 2 >= e.X)) And (polaGracza1(i, j).Location.Y _
                         - 2 <= e.Y And (polaGracza1(i, j).Location.Y + polaGracza1(i, j).Height + 2 >= e.Y)) Then

                    Dim podswietlenie As New SolidBrush(Color.FromArgb(255, 255, 0, 0))
                    g.FillRectangle(podswietlenie, New Rectangle(polaGracza1(i, j).Location.X,
                                                                 polaGracza1(i, j).Location.Y, 41, 41))
                End If
            Next
        Next
        'dodaje tło do pictureboxa co sprawia wrażenie ruchu
        gracz1.Image = BitmapaPodgladowa
        g.Dispose()
        Me.Refresh()
    End Sub

    Private Sub gracz2_MouseMove(sender As Object, e As MouseEventArgs) Handles gracz2.MouseMove
        Dim BitmapaPodgladowa As New Bitmap(PlanszaGlowna)
        Dim g As Graphics = Graphics.FromImage(BitmapaPodgladowa)

        For j As Integer = 0 To 9
            For i As Integer = 0 To 9
                If (polaGracza2(i, j).Location.X - 2 <= e.X And (polaGracza2(i, j).Location.X +
                    polaGracza2(i, j).Width + 2 >= e.X)) And (polaGracza2(i, j).Location.Y _
                    - 2 <= e.Y And (polaGracza2(i, j).Location.Y + polaGracza2(i, j).Height + 2 >= e.Y)) Then
                    Dim podswietlenie As New SolidBrush(Color.FromArgb(255, 255, 0, 0))
                    g.FillRectangle(podswietlenie, New Rectangle(polaGracza2(i, j).Location.X,
                                                                 polaGracza2(i, j).Location.Y, 41, 41))
                End If
            Next
        Next
        gracz2.Image = BitmapaPodgladowa
        g.Dispose()
        Me.Refresh()
    End Sub

Każdy okręt będzie tworzony jako struktura, a te będą przechowywane w kolekcjach. Każdy z graczy będzie posiadał 10 okrętów: 4x pojedyncze, 3x podwójne, 2x potrójne i jeden poczwórny okręt. W tutorialu nie będę pokazywał jak obracać okrętami i jak sprawdzać, czy okręty są za blisko siebie, zasłoniłoby to główne elementy gry. Na pewno każdy, kto będzie chciał grę trochę zmodyfikować, z łatwością doda te elementy. Zajmiemy się teraz układaniem okrętów gracza 1.  Zaczniemy od okrętu czteromasztowego. Przypominam, że będziemy mogli ułożyć go tylko w jednej pozycji i musimy również nałożyć ograniczenie, które uniemożliwi ułożenie go poza obszarem planszy. Dodamy również bitmapę podglądową, która ukaże miejsca ułożonych okrętów.

Należy odblokować opcję w „initRectangles”:

        PlanszaZOkretamiGracza1 = PlanszaGlowna.Clone()
        '    PlanszaZOkretamiGracza2 = PlanszaGlowna.Clone()

Zmodyfikowana zostanie zdarzenie MouseMove dla gracza1:

    Dim PlanszaZOkretamiGracza1 As Bitmap 'plansza podgladowa dla gracza 1
    Dim rodzajOkretuGracz1 As Integer = 0 'pierwszy układany statek
    Dim pozwolNaUmieszczenieOkretu As Boolean = False 'zmienna uniemożliwiająca ulożenie okrętu w miejscu 
    'niedozwolonym
    Dim wybranyokret As Image 'zmienna wymagana jako buffer

    Private Sub gracz1_MouseMove(sender As Object, e As MouseEventArgs) Handles gracz1.MouseMove
        If graRozpoczeta = False Then
            'tworzymy chwilową podglądową bitmapę
            Dim BitmapaPodgladowa As New Bitmap(PlanszaZOkretamiGracza1)
            Dim g As Graphics = Graphics.FromImage(BitmapaPodgladowa)
            'pętla wychwytuje kwadrat nad którym znajduje się kursor myszy
            For j As Integer = 0 To 9
                For i As Integer = 0 To 9
                    If (polaGracza1(i, j).Location.X - 2 <= e.X And (polaGracza1(i, j).Location.X +
                             polaGracza1(i, j).Width + 2 >= e.X)) And (polaGracza1(i, j).Location.Y - 2 <= e.Y _
                             And (polaGracza1(i, j).Location.Y + polaGracza1(i, j).Height + 2 >= e.Y)) Then
                        'generuje nasz okręt
                        If rodzajOkretuGracz1 = 0 Then
                            Dim czteromasztowy As New Bitmap(41, 180)
                            wybranyokret = czteromasztowy
                        ElseIf rodzajOkretuGracz1 = 1 Then
                            Dim czteromasztowy As New Bitmap(41, 134)
                            wybranyokret = czteromasztowy
                        ElseIf rodzajOkretuGracz1 = 2 Then
                            Dim czteromasztowy As New Bitmap(41, 88)
                            wybranyokret = czteromasztowy
                        ElseIf rodzajOkretuGracz1 = 3 Then
                            Dim czteromasztowy As New Bitmap(41, 41)
                            wybranyokret = czteromasztowy
                        End If
                        'wyświetla na zielono, jeśli okręt można ułożyć
                        'na czerwono jeśli nie można go ułożyć
                        Dim okret As New Bitmap(wybranyokret)
                        If sprawdezczymozna(i, j, rodzajOkretuGracz1, PolaulozonychokretowGracz1) Then
                            pozwolNaUmieszczenieOkretu = True
                            'zmienia kolor każdego pixela
                            For Xcount = 0 To okret.Width - 1
                                Dim Ycount As Integer
                                For Ycount = 0 To okret.Height - 1
                                    Dim curPixColor As Color = okret.GetPixel(Xcount, Ycount)
                                    If curPixColor = Color.FromArgb(0, 0, 0, 0) Then
                                        okret.SetPixel(Xcount, Ycount, Color.FromArgb(100, 0, 255, 0))
                                    End If
                                Next
                            Next
                        Else
                            pozwolNaUmieszczenieOkretu = False
                            For Xcount = 0 To okret.Width - 1
                                Dim Ycount As Integer
                                For Ycount = 0 To okret.Height - 1
                                    Dim curPixColor As Color = okret.GetPixel(Xcount, Ycount)
                                    If curPixColor = Color.FromArgb(0, 0, 0, 0) Then
                                        okret.SetPixel(Xcount, Ycount, Color.FromArgb(100, 255, 0, 0))
                                    End If
                                Next
                            Next
                        End If
                        Dim podswietlenie As New SolidBrush(Color.FromArgb(255, 255, 0, 0))

                        ' w tym miejscu nastąpiła zmiana podglądu
                        g.DrawImage(okret, polaGracza1(i, j).Location.X, polaGracza1(i, j).Location.Y)

                    End If
                Next
            Next
            'dodaje tło do pictureboxa co sprawia wrażenie ruchu
            gracz1.Image = BitmapaPodgladowa
            g.Dispose()
            Me.Refresh()
    Else
           'gra rozpoczeta
        End If
    End Sub

    'funkcja zwroci tru jeśli można ułożyć okręt
    Private Function sprawdezczymozna(ByVal i As Integer, ByVal j As Integer, ByVal rodzajOkretuGracz As _
                                      Integer, ByVal PolaulozonychokretowGracz(,) As Boolean) As Boolean
        If rodzajOkretuGracz = 3 Then
            If PolaulozonychokretowGracz(i, j) = False Then
                Return True
            Else
                Return False
            End If
        ElseIf rodzajOkretuGracz = 2 Then
            If i + 1 <= 9 Then
                If PolaulozonychokretowGracz(i, j) = False And PolaulozonychokretowGracz(i + 1, j) = False Then
                    Return True
                Else
                    Return False
                End If
            Else
                Return False
            End If
        ElseIf rodzajOkretuGracz = 1 Then
            If i + 2 <= 9 Then
                If PolaulozonychokretowGracz(i, j) = False And PolaulozonychokretowGracz(i + 1, j) = False _
                    And PolaulozonychokretowGracz(i + 2, j) = False Then
                    Return True
                Else
                    Return False
                End If
            Else
                Return False
            End If
        ElseIf rodzajOkretuGracz = 0 Then
            If i + 3 <= 9 Then
                If PolaulozonychokretowGracz(i, j) = False And PolaulozonychokretowGracz(i + 1, j) = False And
                PolaulozonychokretowGracz(i + 2, j) = False And PolaulozonychokretowGracz(i + 3, j) = False Then
                    Return True
                Else
                    Return False
                End If
            Else
                Return False
            End If
        End If
        Return True
    End Function

Mamy już pierwszy okręt i wypadało, by go ułożyć, kontroluje nam to zmienna „pozwolNaUmieszczenieOkretu” a układanie będzie obsługiwać zdarzenie „MouseClick”. Przy użyciu lewego przycisku myszy kleimy nasz okręt do bitmapy „PlanszaZOkretamiGracza1”  i dodamy strukturę okrętu do kolekcji.

    'Struktura okrętu
    Private Structure Okret
        Dim ZajmowanyObszar As List(Of Rectangle)
        Dim RodzajOkretu As Integer
        Dim ObrazekOkretu As Image
    End Structure
    'kolekcja naszych okrętów
    Private KolekcjaOkretowGracz1 As New Collection

    Private Sub gracz1_MouseClick(sender As Object, e As MouseEventArgs) Handles gracz1.MouseClick
        If graRozpoczeta = False Then
            If pozwolNaUmieszczenieOkretu = True Then
                'Wypełni naszą bitmapę czarnym kolorem
                Dim naszOkret As New Bitmap(wybranyokret)
                For Xcount = 0 To wybranyokret.Width - 1
                    Dim Ycount As Integer
                    For Ycount = 0 To naszOkret.Height - 1
                        Dim curPixColor As Color = naszOkret.GetPixel(Xcount, Ycount)
                        If curPixColor = Color.FromArgb(0, 0, 0, 0) Then
                            naszOkret.SetPixel(Xcount, Ycount, Color.FromArgb(255, 0, 0, 0))
                        End If
                    Next
                Next
                'Ułoży okręt na bitmapie podglądowej
                Dim g As Graphics = Graphics.FromImage(PlanszaZOkretamiGracza1)
                'pętla wychwytuje kwadrat nad którym znajduje się kursor myszy
                For j As Integer = 0 To 9
                    For i As Integer = 0 To 9
                        'pętla namierza położenie kursora
                        If (polaGracza1(i, j).Location.X - 2 <= e.X And (polaGracza1(i, j).Location.X +
                                 polaGracza1(i, j).Width + 2 >= e.X)) And (polaGracza1(i, j).Location.Y - 2 <= _
                               e.Y And (polaGracza1(i, j).Location.Y + polaGracza1(i, j).Height + 2 >= e.Y)) Then
                            'generuje struktury i zmienia aktualny okręt
                            If rodzajOkretuGracz1 = 0 Then

                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 0

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 1, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 2, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 3, j))
                                'blokuje elementy macierzy uniemożliwiając ułozenie na nich okrętów
                                PolaulozonychokretowGracz1(i, j) = True
                                PolaulozonychokretowGracz1(i + 1, j) = True
                                PolaulozonychokretowGracz1(i + 2, j) = True
                                PolaulozonychokretowGracz1(i + 3, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                'zmienia aktualny okręt
                                rodzajOkretuGracz1 = 1

                            ElseIf rodzajOkretuGracz1 = 1 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 1

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 1, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 2, j))
                                PolaulozonychokretowGracz1(i, j) = True
                                PolaulozonychokretowGracz1(i + 1, j) = True
                                PolaulozonychokretowGracz1(i + 2, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                'zmienia aktualny okręt w zależności od ilości ułożonych
                                rodzajOkretuGracz1 = rodzajOkretu(KolekcjaOkretowGracz1, 1)
                            ElseIf rodzajOkretuGracz1 = 2 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 2

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 1, j))
                                PolaulozonychokretowGracz1(i, j) = True
                                PolaulozonychokretowGracz1(i + 1, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                'zmienia aktualny okręt w zależności od ilości ułożonych
                                rodzajOkretuGracz1 = rodzajOkretu(KolekcjaOkretowGracz1, 2)
                            ElseIf rodzajOkretuGracz1 = 3 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 3

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                PolaulozonychokretowGracz1(i, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                rodzajOkretuGracz1 = rodzajOkretu(KolekcjaOkretowGracz1, 3)
                            End If

                            g.DrawImage(naszOkret, polaGracza1(i, j).Location.X, polaGracza1(i, j).Location.Y)
                        End If
                    Next
                Next
                'Warunek sprawdza czy wszystkie okręty są ułozone.
                If rodzajOkretuGracz1 = 4 Then
                    ' Wszystkie okręty ułożone
                    gracz1.Image = PlanszaGlowna
                    gracz1.Enabled = False
                    gracz2.Enabled = True
                Else
                    gracz1.Image = PlanszaZOkretamiGracza1
                End If
                'dodaje tło do pictureboxa co sprawia wrażenie ruchu
                g.Dispose()
                Me.Refresh()
            End If
        Else
            'strzelanie do okrętów
        End If
    End Sub

    'Funkcja sprawdza i zmienia aktualnie wybrany okręt
    Private Function rodzajOkretu(ByRef KolekcjaOkretow As Collection, ByVal aktualnyOkret As Integer) As Integer
        Dim zlicz As Integer = 0
        For g As Integer = 1 To KolekcjaOkretow.Count
            If aktualnyOkret = 1 Then
                If KolekcjaOkretow(g).RodzajOkretu = 1 Then
                    zlicz += 1
                End If
            End If
            If aktualnyOkret = 2 Then
                If KolekcjaOkretow(g).RodzajOkretu = 2 Then
                    zlicz += 1
                End If
            End If
            If aktualnyOkret = 3 Then
                If KolekcjaOkretow(g).RodzajOkretu = 3 Then
                    zlicz += 1
                End If
            End If
        Next
        If zlicz >= aktualnyOkret + 1 Then
            Return zlicz
        Else
            Return aktualnyOkret
        End If
    End Function

W momencie ułożenia wszystkich okrętów plansza zostaje zasłonięta (tak jak to widać na gifie powyżej) a plansza gracza drugiego odblokowana. Gracz drugi układa okręty w taki sam sposób jak gracz 1. Kierują nim takie same zasady. Kiedy gracz drugi ułoży okręty, gra zostanie rozpoczęta. Element strzelania zostanie zawarty w zdarzeniu MouseClick. Pełen kod razem z układaniem okrętów przez gracza 2 dodaje poniżej:

Public Class Form1

    Dim PlanszaGlowna As New Bitmap(478, 478)

    Dim StrzelnicaGracz1 As New Bitmap(478, 478)
    Dim StrzelnicaGracz2 As New Bitmap(478, 478)

    Private polaGracza1(,) As Rectangle
    Private polaGracza2(,) As Rectangle

    Dim graRozpoczeta As Boolean = False

    Private PolaulozonychokretowGracz1(,) As Boolean
    Private PolaulozonychokretowGracz2(,) As Boolean

#Region "Generuje plansze"
    Private Sub initRectangles()

        Dim g As Graphics = Graphics.FromImage(PlanszaGlowna)

        'inicjujemy ponownie nasze tabele
        ReDim polaGracza1(9, 9)
        ReDim polaGracza2(9, 9)

        ReDim PolaulozonychokretowGracz1(9, 9)
        ReDim PolaulozonychokretowGracz2(9, 9)

        Dim kolorPola As New SolidBrush(Color.FromArgb(60, 255, 0, 0))
        'tworzy bitmapę tła zarówno gracza1 jak i gracza2
        For j As Integer = 0 To 9
            For i As Integer = 0 To 9
                polaGracza1(i, j) = New Rectangle(10 + (46 * j), 10 + (46 * i), 41, 41)
                PolaulozonychokretowGracz1(i, j) = False
                polaGracza2(i, j) = New Rectangle(10 + (46 * j), 10 + (46 * i), 41, 41)
                PolaulozonychokretowGracz2(i, j) = False
                g.FillRectangle(kolorPola, polaGracza1(i, j))
            Next
        Next

        'ustawiamy grafikę tła
        gracz1.Image = PlanszaGlowna
        gracz2.Image = PlanszaGlowna
        PlanszaZOkretamiGracza1 = PlanszaGlowna.Clone()
        PlanszaZOkretamiGracza2 = PlanszaGlowna.Clone()
        g.Dispose()
        Me.Refresh()
    End Sub
#End Region

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        initRectangles()
    End Sub

    Dim pozwolNaUmieszczenieOkretu As Boolean = False 'zmienna uniemożliwiająca ulożenie okrętu w miejscu 
    'niedozwolonym
    Dim wybranyokret As Image 'zmienna wymagana jako buffer

#Region "Strefa gracza1"
    Dim PlanszaZOkretamiGracza1 As Bitmap 'plansza podgladowa dla gracza 1
    Dim rodzajOkretuGracz1 As Integer = 0 'pierwszy układany statek

    Private Sub gracz1_MouseMove(sender As Object, e As MouseEventArgs) Handles gracz1.MouseMove
        If graRozpoczeta = False Then
            'tworzymy chwilową podglądową bitmapę
            Dim BitmapaPodgladowa As New Bitmap(PlanszaZOkretamiGracza1)
            Dim g As Graphics = Graphics.FromImage(BitmapaPodgladowa)
            'pętla wychwytuje kwadrat nad którym znajduje się kursor myszy
            For j As Integer = 0 To 9
                For i As Integer = 0 To 9
                    If (polaGracza1(i, j).Location.X - 2 <= e.X And (polaGracza1(i, j).Location.X +
                             polaGracza1(i, j).Width + 2 >= e.X)) And (polaGracza1(i, j).Location.Y - 2 <= _ 
                          e.Y And (polaGracza1(i, j).Location.Y + polaGracza1(i, j).Height + 2 >= e.Y)) Then
                        'generuje nasz okręt
                        If rodzajOkretuGracz1 = 0 Then
                            Dim czteromasztowy As New Bitmap(41, 180)
                            wybranyokret = czteromasztowy
                        ElseIf rodzajOkretuGracz1 = 1 Then
                            Dim czteromasztowy As New Bitmap(41, 134)
                            wybranyokret = czteromasztowy
                        ElseIf rodzajOkretuGracz1 = 2 Then
                            Dim czteromasztowy As New Bitmap(41, 88)
                            wybranyokret = czteromasztowy
                        ElseIf rodzajOkretuGracz1 = 3 Then
                            Dim czteromasztowy As New Bitmap(41, 41)
                            wybranyokret = czteromasztowy
                        End If
                        'wyświetla na zielono, jeśli okręt można ułożyć
                        'na czerwono jeśli nie można go ułożyć
                        Dim okret As New Bitmap(wybranyokret)
                        If sprawdezczymozna(i, j, rodzajOkretuGracz1, PolaulozonychokretowGracz1) Then
                            pozwolNaUmieszczenieOkretu = True
                            'zmienia kolor każdego pixela
                            For Xcount = 0 To okret.Width - 1
                                Dim Ycount As Integer
                                For Ycount = 0 To okret.Height - 1
                                    Dim curPixColor As Color = okret.GetPixel(Xcount, Ycount)
                                    If curPixColor = Color.FromArgb(0, 0, 0, 0) Then
                                        okret.SetPixel(Xcount, Ycount, Color.FromArgb(100, 0, 255, 0))
                                    End If
                                Next
                            Next
                        Else
                            pozwolNaUmieszczenieOkretu = False
                            For Xcount = 0 To okret.Width - 1
                                Dim Ycount As Integer
                                For Ycount = 0 To okret.Height - 1
                                    Dim curPixColor As Color = okret.GetPixel(Xcount, Ycount)
                                    If curPixColor = Color.FromArgb(0, 0, 0, 0) Then
                                        okret.SetPixel(Xcount, Ycount, Color.FromArgb(100, 255, 0, 0))
                                    End If
                                Next
                            Next
                        End If
                        Dim podswietlenie As New SolidBrush(Color.FromArgb(255, 255, 0, 0))

                        ' w tym miejscu nastąpiła zmiana podglądu
                        g.DrawImage(okret, polaGracza1(i, j).Location.X, polaGracza1(i, j).Location.Y)

                    End If
                Next
            Next
            'dodaje tło do pictureboxa co sprawia wrażenie ruchu
            gracz1.Image = BitmapaPodgladowa
            g.Dispose()
            Me.Refresh()
        Else
            'gra rozpoczeta
        End If
    End Sub


    'Struktura okrętu
    Private Structure Okret
        Dim ZajmowanyObszar As List(Of Rectangle)
        Dim RodzajOkretu As Integer
        Dim ObrazekOkretu As Image
    End Structure
    'kolekcja naszych okrętów
    Private KolekcjaOkretowGracz1 As New Collection

    Private Sub gracz1_MouseClick(sender As Object, e As MouseEventArgs) Handles gracz1.MouseClick
        If graRozpoczeta = False Then
            If pozwolNaUmieszczenieOkretu = True Then
                'Wypełni naszą bitmapę czarnym kolorem
                Dim naszOkret As New Bitmap(wybranyokret)
                For Xcount = 0 To wybranyokret.Width - 1
                    Dim Ycount As Integer
                    For Ycount = 0 To naszOkret.Height - 1
                        Dim curPixColor As Color = naszOkret.GetPixel(Xcount, Ycount)
                        If curPixColor = Color.FromArgb(0, 0, 0, 0) Then
                            naszOkret.SetPixel(Xcount, Ycount, Color.FromArgb(255, 0, 0, 0))
                        End If
                    Next
                Next
                'Ułoży okręt na bitmapie podglądowej
                Dim g As Graphics = Graphics.FromImage(PlanszaZOkretamiGracza1)
                'pętla wychwytuje kwadrat nad którym znajduje się kursor myszy
                For j As Integer = 0 To 9
                    For i As Integer = 0 To 9
                        'pętla namierza położenie kursora
                        If (polaGracza1(i, j).Location.X - 2 <= e.X And (polaGracza1(i, j).Location.X +
                                 polaGracza1(i, j).Width + 2 >= e.X)) And (polaGracza1(i, j).Location.Y - 2 _
                         <= e.Y And (polaGracza1(i, j).Location.Y + polaGracza1(i, j).Height + 2 >= e.Y)) Then
                            'generuje struktury i zmienia aktualny okręt
                            If rodzajOkretuGracz1 = 0 Then

                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 0

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 1, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 2, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 3, j))
                                'blokuje elementy macierzy uniemożliwiając ułozenie na nich okrętów
                                PolaulozonychokretowGracz1(i, j) = True
                                PolaulozonychokretowGracz1(i + 1, j) = True
                                PolaulozonychokretowGracz1(i + 2, j) = True
                                PolaulozonychokretowGracz1(i + 3, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                'zmienia aktualny okręt
                                rodzajOkretuGracz1 = 1

                            ElseIf rodzajOkretuGracz1 = 1 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 1

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 1, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 2, j))
                                PolaulozonychokretowGracz1(i, j) = True
                                PolaulozonychokretowGracz1(i + 1, j) = True
                                PolaulozonychokretowGracz1(i + 2, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                'zmienia aktualny okręt w zależności od ilości ułożonych
                                rodzajOkretuGracz1 = rodzajOkretu(KolekcjaOkretowGracz1, 1)
                            ElseIf rodzajOkretuGracz1 = 2 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 2

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 1, j))
                                PolaulozonychokretowGracz1(i, j) = True
                                PolaulozonychokretowGracz1(i + 1, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                'zmienia aktualny okręt w zależności od ilości ułożonych
                                rodzajOkretuGracz1 = rodzajOkretu(KolekcjaOkretowGracz1, 2)
                            ElseIf rodzajOkretuGracz1 = 3 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 3

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                PolaulozonychokretowGracz1(i, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                rodzajOkretuGracz1 = rodzajOkretu(KolekcjaOkretowGracz1, 3)
                            End If

                            g.DrawImage(naszOkret, polaGracza1(i, j).Location.X, polaGracza1(i, j).Location.Y)
                        End If
                    Next
                Next
                'Warunek sprawdza czy wszystkie okręty są ułozone.
                If rodzajOkretuGracz1 = 4 Then
                    ' Wszystkie okręty ułożone
                    gracz1.Image = PlanszaGlowna
                    gracz1.Enabled = False
                    gracz2.Enabled = True
                Else
                    gracz1.Image = PlanszaZOkretamiGracza1
                End If
                'dodaje tło do pictureboxa co sprawia wrażenie ruchu
                g.Dispose()
                Me.Refresh()
            End If
        Else
            'strzelanie do okrętów
        End If
    End Sub
#End Region

#Region "Strefa gracza2"
    Dim PlanszaZOkretamiGracza2 As Bitmap 'plansza podgladowa dla gracza 2
    Dim rodzajOkretuGracz2 As Integer = 0 'pierwszy układany statek
    'niedozwolonym

    Private Sub gracz2_MouseMove(sender As Object, e As MouseEventArgs) Handles gracz2.MouseMove
        If graRozpoczeta = False Then
            'tworzymy chwilową podglądową bitmapę
            Dim BitmapaPodgladowa As New Bitmap(PlanszaZOkretamiGracza2)
            Dim g As Graphics = Graphics.FromImage(BitmapaPodgladowa)
            'pętla wychwytuje kwadrat nad którym znajduje się kursor myszy
            For j As Integer = 0 To 9
                For i As Integer = 0 To 9
                    If (polaGracza2(i, j).Location.X - 2 <= e.X And (polaGracza2(i, j).Location.X +
                             polaGracza2(i, j).Width + 2 >= e.X)) And (polaGracza2(i, j).Location.Y - 2 <= _
                           e.Y And (polaGracza2(i, j).Location.Y + polaGracza2(i, j).Height + 2 >= e.Y)) Then
                        'generuje nasz okręt
                        If rodzajOkretuGracz2 = 0 Then
                            Dim czteromasztowy As New Bitmap(41, 180)
                            wybranyokret = czteromasztowy
                        ElseIf rodzajOkretuGracz2 = 1 Then
                            Dim czteromasztowy As New Bitmap(41, 134)
                            wybranyokret = czteromasztowy
                        ElseIf rodzajOkretuGracz2 = 2 Then
                            Dim czteromasztowy As New Bitmap(41, 88)
                            wybranyokret = czteromasztowy
                        ElseIf rodzajOkretuGracz2 = 3 Then
                            Dim czteromasztowy As New Bitmap(41, 41)
                            wybranyokret = czteromasztowy
                        End If
                        'wyświetla na zielono, jeśli okręt można ułożyć
                        'na czerwono jeśli nie można go ułożyć
                        Dim okret As New Bitmap(wybranyokret)
                        If sprawdezczymozna(i, j, rodzajOkretuGracz2, PolaulozonychokretowGracz2) Then
                            pozwolNaUmieszczenieOkretu = True
                            'zmienia kolor każdego pixela
                            For Xcount = 0 To okret.Width - 1
                                Dim Ycount As Integer
                                For Ycount = 0 To okret.Height - 1
                                    Dim curPixColor As Color = okret.GetPixel(Xcount, Ycount)
                                    If curPixColor = Color.FromArgb(0, 0, 0, 0) Then
                                        okret.SetPixel(Xcount, Ycount, Color.FromArgb(100, 0, 255, 0))
                                    End If
                                Next
                            Next
                        Else
                            pozwolNaUmieszczenieOkretu = False
                            For Xcount = 0 To okret.Width - 1
                                Dim Ycount As Integer
                                For Ycount = 0 To okret.Height - 1
                                    Dim curPixColor As Color = okret.GetPixel(Xcount, Ycount)
                                    If curPixColor = Color.FromArgb(0, 0, 0, 0) Then
                                        okret.SetPixel(Xcount, Ycount, Color.FromArgb(100, 255, 0, 0))
                                    End If
                                Next
                            Next
                        End If
                        Dim podswietlenie As New SolidBrush(Color.FromArgb(255, 255, 0, 0))

                        ' w tym miejscu nastąpiła zmiana podglądu
                        g.DrawImage(okret, polaGracza2(i, j).Location.X, polaGracza2(i, j).Location.Y)

                    End If
                Next
            Next
            'dodaje tło do pictureboxa co sprawia wrażenie ruchu
            gracz2.Image = BitmapaPodgladowa
            g.Dispose()
            Me.Refresh()
        Else
            'gra rozpoczeta
        End If
    End Sub

    'kolekcja okrętów gracza 2
    Private KolekcjaOkretowGracz2 As New Collection
    Private Sub gracz2_MouseClick(sender As Object, e As MouseEventArgs) Handles gracz2.MouseClick
        If graRozpoczeta = False Then
            If pozwolNaUmieszczenieOkretu = True Then
                'Wypełni naszą bitmapę czarnym kolorem
                Dim naszOkret As New Bitmap(wybranyokret)
                For Xcount = 0 To wybranyokret.Width - 1
                    Dim Ycount As Integer
                    For Ycount = 0 To naszOkret.Height - 1
                        Dim curPixColor As Color = naszOkret.GetPixel(Xcount, Ycount)
                        If curPixColor = Color.FromArgb(0, 0, 0, 0) Then
                            naszOkret.SetPixel(Xcount, Ycount, Color.FromArgb(255, 0, 0, 0))
                        End If
                    Next
                Next
                'Ułoży okręt na bitmapie podglądowej
                Dim g As Graphics = Graphics.FromImage(PlanszaZOkretamiGracza2)
                'pętla wychwytuje kwadrat nad którym znajduje się kursor myszy
                For j As Integer = 0 To 9
                    For i As Integer = 0 To 9
                        'pętla namierza położenie kursora
                        If (polaGracza2(i, j).Location.X - 2 <= e.X And (polaGracza2(i, j).Location.X +
                                 polaGracza2(i, j).Width + 2 >= e.X)) And (polaGracza2(i, j).Location.Y - 2 _
                          <= e.Y And (polaGracza2(i, j).Location.Y + polaGracza2(i, j).Height + 2 >= e.Y)) Then
                            'generuje struktury i zmienia aktualny okręt
                            If rodzajOkretuGracz2 = 0 Then

                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 0

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza2(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza2(i + 1, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza2(i + 2, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza2(i + 3, j))
                                'blokuje elementy macierzy uniemożliwiając ułozenie na nich okrętów
                                PolaulozonychokretowGracz2(i, j) = True
                                PolaulozonychokretowGracz2(i + 1, j) = True
                                PolaulozonychokretowGracz2(i + 2, j) = True
                                PolaulozonychokretowGracz2(i + 3, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz2.Add(NowyOkret)
                                'zmienia aktualny okręt
                                rodzajOkretuGracz2 = 1

                            ElseIf rodzajOkretuGracz2 = 1 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 1

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza2(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza2(i + 1, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza2(i + 2, j))
                                PolaulozonychokretowGracz2(i, j) = True
                                PolaulozonychokretowGracz2(i + 1, j) = True
                                PolaulozonychokretowGracz2(i + 2, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz2.Add(NowyOkret)
                                'zmienia aktualny okręt w zależności od ilości ułożonych
                                rodzajOkretuGracz2 = rodzajOkretu(KolekcjaOkretowGracz2, 1)
                            ElseIf rodzajOkretuGracz2 = 2 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 2

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza2(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza2(i + 1, j))
                                PolaulozonychokretowGracz2(i, j) = True
                                PolaulozonychokretowGracz2(i + 1, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz2.Add(NowyOkret)
                                'zmienia aktualny okręt w zależności od ilości ułożonych
                                rodzajOkretuGracz2 = rodzajOkretu(KolekcjaOkretowGracz2, 2)
                            ElseIf rodzajOkretuGracz2 = 3 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 3

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza2(i, j))
                                PolaulozonychokretowGracz2(i, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz2.Add(NowyOkret)
                                rodzajOkretuGracz2 = rodzajOkretu(KolekcjaOkretowGracz2, 3)
                            End If

                            g.DrawImage(naszOkret, polaGracza2(i, j).Location.X, polaGracza2(i, j).Location.Y)
                        End If
                    Next
                Next
                'Warunek sprawdza czy wszystkie okręty są ułozone.
                If rodzajOkretuGracz2 = 4 Then
                    ' Wszystkie okręty ułożone
                    gracz2.Image = PlanszaGlowna
                    gracz2.Enabled = True
                    gracz1.Enabled = False
                    graRozpoczeta = True
                    MsgBox("Gra rozpoczeła się!! Zaczyna gracz 1.")
                Else
                    gracz2.Image = PlanszaZOkretamiGracza2
                End If
                'dodaje tło do pictureboxa co sprawia wrażenie ruchu
                g.Dispose()
                Me.Refresh()
            End If
        Else
            'strzelanie do okrętów
        End If
    End Sub
#End Region

#Region "Strefa wspólna"
    'funkcja zwroci true jeśli można ułożyć okręt
    Private Function sprawdezczymozna(ByVal i As Integer, ByVal j As Integer, ByVal rodzajOkretuGracz As _
                                      Integer, ByVal PolaulozonychokretowGracz(,) As Boolean) As Boolean
        If rodzajOkretuGracz = 3 Then
            If PolaulozonychokretowGracz(i, j) = False Then
                Return True
            Else
                Return False
            End If
        ElseIf rodzajOkretuGracz = 2 Then
            If i + 1 <= 9 Then
                If PolaulozonychokretowGracz(i, j) = False And PolaulozonychokretowGracz(i + 1, j) = False Then
                    Return True
                Else
                    Return False
                End If
            Else
                Return False
            End If
        ElseIf rodzajOkretuGracz = 1 Then
            If i + 2 <= 9 Then
                If PolaulozonychokretowGracz(i, j) = False And PolaulozonychokretowGracz(i + 1, j) = _
                    False And PolaulozonychokretowGracz(i + 2, j) = False Then
                    Return True
                Else
                    Return False
                End If
            Else
                Return False
            End If
        ElseIf rodzajOkretuGracz = 0 Then
            If i + 3 <= 9 Then
                If PolaulozonychokretowGracz(i, j) = False And PolaulozonychokretowGracz(i + 1, j) = False And
              PolaulozonychokretowGracz(i + 2, j) = False And PolaulozonychokretowGracz(i + 3, j) = False Then
                    Return True
                Else
                    Return False
                End If
            Else
                Return False
            End If
        End If
        Return True
    End Function

    'Funkcja sprawdza i zmienia aktualnie wybrany okręt
 Private Function rodzajOkretu(ByRef KolekcjaOkretow As Collection, ByVal aktualnyOkret As Integer) As Integer
        Dim zlicz As Integer = 0
        For g As Integer = 1 To KolekcjaOkretow.Count
            If aktualnyOkret = 1 Then
                If KolekcjaOkretow(g).RodzajOkretu = 1 Then
                    zlicz += 1
                End If
            End If
            If aktualnyOkret = 2 Then
                If KolekcjaOkretow(g).RodzajOkretu = 2 Then
                    zlicz += 1
                End If
            End If
            If aktualnyOkret = 3 Then
                If KolekcjaOkretow(g).RodzajOkretu = 3 Then
                    zlicz += 1
                End If
            End If
        Next
        If zlicz >= aktualnyOkret + 1 Then
            Return zlicz
        Else
            Return aktualnyOkret
        End If
    End Function
#End Region
End Class

Mam nadziej, że nadążacie. Po dokonaniu tych zmian układanie okrętów mamy już z głowy:

Teraz kiedy pojawił się komunikat, możemy zaprosić gracza 1 do gry. To on rozpoczyna grę, chociaż można by było wprowadzić element losowy, który wyznaczałby gracza zaczynającego grę. Gracze będą strzelać za pomocą lewego przycisku myszy. Kiedy kursor myszy najedzie na dostępny kwadrat do strzału, zostanie zmieniony ze strzałki na rączkę. Kiedy gracz trafi okręt, będzie miał do dyspozycji kolejny strzał. Plansze zostaną odblokowane w zależności od tego, który gracz aktualnie wykonuje strzał. Jeśli będzie to gracz 1, wtedy odblokowaniu podlega plansza gracza 2. Gra kończy się, wtedy kiedy kolekcja okrętów gracza1 lub gracza2 będzie pusta. Zajmijmy się dodaniem ważnych zmiennych, lecz jeszcze niewpisanych w nasz kod:

    Dim listaPudloGracz1 As New List(Of Rectangle)
    Dim listaPudloGracz2 As New List(Of Rectangle)
    Dim listatrafioneGracz1 As New List(Of Rectangle)
    Dim listatrafioneGracz2 As New List(Of Rectangle)
    Dim pozwolnaStrzal As Boolean = False

Zmienne przechowują trafione kwadraty i jeśli spudłujemy, kwadraty puste. Zajmijmy się ustawieniem kursora rączki nad możliwym do wybrania kwadratem. Przechodzimy do zdarzenia gracz1_MouseMove i dodajemy następujący kod:

    Private Sub gracz1_MouseMove(sender As Object, e As MouseEventArgs) Handles gracz1.MouseMove
        If graRozpoczeta = False Then
            (......)
        Else
            'wstępnie kursor ustawiamy na strzałkę
            Dim cursorHand As Boolean = False
            For j As Integer = 0 To 9
                For i As Integer = 0 To 9
                    If (polaGracza1(i, j).Location.X - 2 <= e.X And (polaGracza1(i, j).Location.X +
                             polaGracza1(i, j).Width + 2 >= e.X)) And (polaGracza1(i, j).Location.Y - 2 <= e.Y _
                             And (polaGracza1(i, j).Location.Y + polaGracza1(i, j).Height + 2 >= e.Y)) Then
                        'sprawdza czy kwadrat nad którym znajduje się kursor nie zawiera się w listach
                        If Not listaPudloGracz2.Contains(polaGracza1(i, j)) And Not _
                        listatrafioneGracz2.Contains(polaGracza1(i, j)) Then
                            cursorHand = True
                        End If

                    End If
                Next
            Next
            'ustawia odpowiedni kursor
            If cursorHand = True Then
                Me.Cursor = Cursors.Hand
                pozwolnaStrzal = True
            Else
                Me.Cursor = Cursors.Arrow
                pozwolnaStrzal = False
            End If
        End If
    End Sub

Efekt prezentuje poniższy gif:

Oczywiście elementem dyskusyjnym są kolory przestawione w programie, możecie użyć dowolnych kolorów, możecie podświetlić panel aktualnie wykonującego strzał gracza, dodać ładną grafikę statków, a nie czarne prostokąty. Każdy taki element urozmaici i wzbogaci grę. Zobaczcie grę zademonstrowaną na wstępie tego wpisu. Wróćmy do naszej gry. Został nam ostatni element, chyba najtrudniejszy, tak myślę. Najpierw weźmiemy czystą bitmapę „StrzelicaGracza” to na jej powierzchnię będziemy nanosić obrazki zatopionych okrętów. Następnie używając znanej już nam pętli, sprawdzimy, w którym miejscu znajduje się kursor myszy, sprawdzimy, czy ten obszar nie znajduje się już w liście trafionych lub liście spudłowanych. Jeśli nie wtedy sprawdzamy każdy element kolekcji (w zależności od miejsca, w którym się znajdujemy KolekcjaOkretowGracz1 lub KolekcjaOkretowGracz2) czy przypadkiem nasz kwadrat tam się nie znajduje. Jeśli znajduje się, wtedy dokonaliśmy trafienia okrętu przeciwnika. Następnie sprawdzamy, czy wszystkie elementy trafionego okrętu znajdują się w naszej liście trafionych obiektów. Jeśli tak nanosimy sylwetkę okrętu na bitmapę strzelnicy. Na koniec rysujemy pola, podstawiamy obrazek i jeśli gracz trafił, kontynuuje grę, w tym miejscu sprawdzamy, jeszcze czy może gra nie jest już skończona.

 Private Sub gracz1_MouseClick(sender As Object, e As MouseEventArgs) Handles gracz1.MouseClick
        If graRozpoczeta = False Then
            If pozwolNaUmieszczenieOkretu = True Then
                'Wypełni naszą bitmapę czarnym kolorem
                Dim naszOkret As New Bitmap(wybranyokret)
                For Xcount = 0 To wybranyokret.Width - 1
                    Dim Ycount As Integer
                    For Ycount = 0 To naszOkret.Height - 1
                        Dim curPixColor As Color = naszOkret.GetPixel(Xcount, Ycount)
                        If curPixColor = Color.FromArgb(0, 0, 0, 0) Then
                            naszOkret.SetPixel(Xcount, Ycount, Color.FromArgb(255, 0, 0, 0))
                        End If
                    Next
                Next
                'Ułoży okręt na bitmapie podglądowej
                Dim g As Graphics = Graphics.FromImage(PlanszaZOkretamiGracza1)
                'pętla wychwytuje kwadrat nad którym znajduje się kursor myszy
                For j As Integer = 0 To 9
                    For i As Integer = 0 To 9
                        'pętla namierza położenie kursora
                        If (polaGracza1(i, j).Location.X - 2 <= e.X And (polaGracza1(i, j).Location.X +
                                 polaGracza1(i, j).Width + 2 >= e.X)) And (polaGracza1(i, j).Location.Y - 2 <= e.Y _
                                 And (polaGracza1(i, j).Location.Y + polaGracza1(i, j).Height + 2 >= e.Y)) Then
                            'generuje struktury i zmienia aktualny okręt
                            If rodzajOkretuGracz1 = 0 Then

                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 0

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 1, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 2, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 3, j))
                                'blokuje elementy macierzy uniemożliwiając ułozenie na nich okrętów
                                PolaulozonychokretowGracz1(i, j) = True
                                PolaulozonychokretowGracz1(i + 1, j) = True
                                PolaulozonychokretowGracz1(i + 2, j) = True
                                PolaulozonychokretowGracz1(i + 3, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                'zmienia aktualny okręt
                                rodzajOkretuGracz1 = 1

                            ElseIf rodzajOkretuGracz1 = 1 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 1

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 1, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 2, j))
                                PolaulozonychokretowGracz1(i, j) = True
                                PolaulozonychokretowGracz1(i + 1, j) = True
                                PolaulozonychokretowGracz1(i + 2, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                'zmienia aktualny okręt w zależności od ilości ułożonych
                                rodzajOkretuGracz1 = rodzajOkretu(KolekcjaOkretowGracz1, 1)
                            ElseIf rodzajOkretuGracz1 = 2 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 2

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i + 1, j))
                                PolaulozonychokretowGracz1(i, j) = True
                                PolaulozonychokretowGracz1(i + 1, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                'zmienia aktualny okręt w zależności od ilości ułożonych
                                rodzajOkretuGracz1 = rodzajOkretu(KolekcjaOkretowGracz1, 2)
                            ElseIf rodzajOkretuGracz1 = 3 Then
                                Dim NowyOkret As Okret
                                NowyOkret.RodzajOkretu = 3

                                Dim ListaZajmowanegoMiejsca As New List(Of Rectangle)
                                ListaZajmowanegoMiejsca.Add(polaGracza1(i, j))
                                PolaulozonychokretowGracz1(i, j) = True

                                NowyOkret.ZajmowanyObszar = ListaZajmowanegoMiejsca
                                NowyOkret.ObrazekOkretu = naszOkret
                                KolekcjaOkretowGracz1.Add(NowyOkret)
                                rodzajOkretuGracz1 = rodzajOkretu(KolekcjaOkretowGracz1, 3)
                            End If

                            g.DrawImage(naszOkret, polaGracza1(i, j).Location.X, polaGracza1(i, j).Location.Y)
                        End If
                    Next
                Next
                'Warunek sprawdza czy wszystkie okręty są ułozone.
                If rodzajOkretuGracz1 = 4 Then
                    ' Wszystkie okręty ułożone
                    gracz1.Image = PlanszaGlowna
                    gracz1.Enabled = False
                    gracz2.Enabled = True
                Else
                    gracz1.Image = PlanszaZOkretamiGracza1
                End If
                'dodaje tło do pictureboxa co sprawia wrażenie ruchu
                g.Dispose()
                Me.Refresh()
            End If
        Else
            'bitmapa z naniesionymi okrętami
            Dim BitmapaPodgladowa As New Bitmap(StrzelnicaGracz2)
            Dim g As Graphics = Graphics.FromImage(BitmapaPodgladowa)
            'zmienne kontroolujące strzał
            Dim trafiony As Boolean = False
            Dim pustyStrzal As Boolean = True
            Dim pudlo As Boolean = True
            'index elementu do usunięcia
            Dim elementDoUsunieciaZkolekcjii As Integer = 0
            Dim wybranyObszar As Rectangle 'aktualny element

            For j As Integer = 0 To 9
                For i As Integer = 0 To 9
                    If (polaGracza1(i, j).Location.X - 2 <= e.X And (polaGracza1(i, j).Location.X +
                             polaGracza1(i, j).Width + 2 >= e.X)) And (polaGracza1(i, j).Location.Y - 2 <= e.Y And (polaGracza1(i, j).Location.Y + polaGracza1(i, j).Height + 2 >= e.Y)) Then

                        wybranyObszar = polaGracza1(i, j)

                        If Not listaPudloGracz2.Contains(polaGracza1(i, j)) And Not listatrafioneGracz2.Contains(polaGracza1(i, j)) Then
                            pustyStrzal = False
                            For f As Integer = 1 To KolekcjaOkretowGracz1.Count
                                For t As Integer = 0 To KolekcjaOkretowGracz1(f).ZajmowanyObszar.count - 1
                                    If KolekcjaOkretowGracz1(f).ZajmowanyObszar(t).location = polaGracza1(i, j).Location Then
                                        trafiony = True
                                        pudlo = False
                                        listatrafioneGracz2.Add(polaGracza1(i, j))
                                        Dim kontynuuj As Boolean = True
                                        For y As Integer = 0 To KolekcjaOkretowGracz1(f).ZajmowanyObszar.count - 1
                                            If Not listatrafioneGracz2.Contains(KolekcjaOkretowGracz1(f).ZajmowanyObszar(y)) Then
                                                kontynuuj = False
                                                Exit For
                                            End If
                                        Next
                                        'namaluj okręt jeśli jest zestrzelony
                                        If kontynuuj = True Then
                                            Dim okret As Image = KolekcjaOkretowGracz1(f).ObrazekOkretu
                                            g.DrawImage(okret, KolekcjaOkretowGracz1(f).ZajmowanyObszar(0).Location.X, KolekcjaOkretowGracz1(f).ZajmowanyObszar(0).Location.Y)
                                            StrzelnicaGracz2 = BitmapaPodgladowa.Clone()
                                            elementDoUsunieciaZkolekcjii = f
                                        End If
                                    End If
                                Next
                            Next
                        End If
                    End If
                Next
            Next
            'dodaj do listy pudło jesli gracz spudłował
            If pudlo = True Then
                listaPudloGracz2.Add(wybranyObszar)
            End If
            'pędzle do malowania obszaru rozgrywki
            Dim kolorPola As New SolidBrush(Color.FromArgb(60, 255, 0, 0))
            Dim kolorTrafiony As New SolidBrush(Color.FromArgb(100, 255, 0, 0))

            For j As Integer = 0 To 9
                For i As Integer = 0 To 9
                    If Not listaPudloGracz2.Contains(polaGracza1(i, j)) And Not listatrafioneGracz2.Contains(polaGracza1(i, j)) Then
                        g.FillRectangle(kolorPola, polaGracza1(i, j))
                    End If
                    If listatrafioneGracz2.Contains(polaGracza1(i, j)) Then
                        g.FillRectangle(kolorTrafiony, polaGracza1(i, j))
                    End If
                Next
            Next
            'podstaw tło
            gracz1.Image = BitmapaPodgladowa

            If pustyStrzal = False Then
                If trafiony = False Then
                    gracz1.Enabled = False
                    gracz2.Enabled = True
                    Me.Cursor = Cursors.Arrow
                Else
                    If elementDoUsunieciaZkolekcjii > 0 Then
                        'usówa element z kolekcji
                        KolekcjaOkretowGracz1.Remove(elementDoUsunieciaZkolekcjii)
                    End If
                    If KolekcjaOkretowGracz1.Count = 0 Then
                        'koniec gry
                        MsgBox("Koniec gry wygrał gracz 2!")
                        gracz1.Enabled = False
                        gracz2.Enabled = False
                    End If
                End If
            End If

            g.Dispose()
            Me.Refresh()
        End If
    End Sub

To samo tylko w sposób odwrócony robimy dla gracza 1 w obszarze gracza 2.

To by było na tyle. Grę musicie sami dopracować według własnych pomysłów. Szkielet gry macie dostępny, więc musicie się postarać. Jeśli wymyślicie coś ciekawego, to prześlijcie mi zdjęcia to umieszczę je na blogu 😉

Tak jak zawsze do pobrania:

Pełen kod gry:  Okrety_visualmonsters.cba.pl.txt

Projekt:  Okrety_VisualMonsters.cba.pl.zip

 

 

Permalink do tego artykułu: https://visualmonsters.cba.pl/gra-w-statki/

Dodaj komentarz

Twój adres email nie będzie publikowany.