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




