Dzisiaj zajmiemy się kolizją obiektów, będziemy bazować zna sterowaniu i projektu gry którą zaczęliśmy we wcześniejszym tutorialu: tutaj
Dorobimy sobie kulki które nasz statek będzie mógł złapać i zdobywać tym samym punkty.Trochę zmienimy sobie naszą formę. Wcześniej nasz pictureBox miał ustawione „Doc: fill” należy to zmienić na „none”. Dodajemy dodatkowy Panel który będzie przechowywał wyniki itp:
Gdy panel jest dodany dodajemy kilka labeli i ustawiamy wszystkie elementy jak w tabeli:
Rodzaj elementu | Nazwa elementu | ustawienia |
---|---|---|
Form | Form1 | Name: Form1 MaximizeBox: false MinimizeBox: false MaximumSize: 600; 400 MinimumSize: 600; 400 Text: Łapanie gemów Size: 600; 400 StartPosition: CenterScreen |
PictureBox | PictureBox1 | Name: PictureBox1 Anchor: Top, Bottom, Left, Right Size: 817; 338 Location: 12; 37 Dodałem jedną serię danych. |
Panel | Panel1 | Dock: Top Size: 584;50 Name: Panel1 |
Label | Label1 | Text: „Wynik:” Location: 12;22 |
Label | Label2 | Text: „Gem top:” Location: 163;9 |
Label | Label3 | Text: „Gem left:” Location: 163;31 |
Label | Label4 | Text: „Statek top:” Location: 339;9 |
Label | Label5 | Text: „Statek Left:” Location:339;31 |
Label | Wynik_wartosc | Text: „0” Name: Wynik_wartosc Location: 12;22 |
Label | Gemtop | Text: „0” Name: Gemtop Location: 219;9 |
Label | Gemleft | Text: „0” Name: Gemleft Location: 219;31 |
Label | Statektop | Text: „0” Name: Statektop Location: 404;9 |
Label | Statekleft | Text: „0” Name: Statekleft Location: 404;31 |
Po ułożeniu tych elementów nasza forma będzie wyglądała tak:
Teraz zajmiemy się teorią. Kiedy mówimy o kolizji obiektów, otóż w momencie nałożenia się dwóch obiektów w odniesieniu do obiektu matki. Jak to wygląda:
Czas stworzyć sobie nasz nowy obiekt. Nasz nowy obiekt będzie pojawiał się w losowym miejscu na planszy. Najpierw określimy sobie wymiary naszego obiektu. W moim przypadku będzie to 10×10 a kolor dam zielony. Następnie ograniczymy możliwość pojawienia się obiektu do strefy kropkowanej równej długości planszy – długość naszego obiektu i szerokości planszy minus szerokość naszego obiektu, na obrazku obszar kropkowany:
Nie chcemy aby nasz obiekt pojawił się poza planszą gdyż nie będziemy mogli go wtedy złapać. Do stworzenia obiektu możemy użyć gotowych obiektów jak panel, picturebox lub stworzyć za pomocą bibliotek drawing. Właśnie za pomocą tej metody stworzymy sobie nasze gemy. Problem z tą metodą jest taki, że nasze gemy będą musiały być cały czas monitorowane przez nas aby ich lokalizacja była stale zapisywana i porównywana z lokalizacją statku. Najpierw pobieramy sobie bublioteki:
1 2 3 4 5 6 7 |
Imports System.Drawing Imports System.Drawing.Drawing2D Imports System.Drawing.Imaging Imports System.Drawing.Text Public Class Form1 (...) |
Bez nich nic nie namalujemy. Dodajemy sobie lokalne zmienne które będą odpowiedzialne, za niektóre elementy gry:
1 2 3 4 |
Dim myBrush As New System.Drawing.SolidBrush(System.Drawing.Color.Green) 'Dodaje kolorek pod zmienną myBrush posłuży za wypełnienie Dim startposGemL As Integer 'położenie gem'a lewo Dim startposGemT As Integer 'położenie gem'a top Dim wynik As Integer = 0 'Początkowy wynik |
Do suba odpowiedzialnego za rozpoczęcie gry dodajemy linijki:
1 2 3 4 |
Public Sub start() startposGemL = Int(Rnd() * (PictureBox1.Width - 2 * 10) + 10) 'ustawia początkową wartość left dla gemu startposGemT = Int(Rnd() * (PictureBox1.Height - 2 * 10) + 10) 'ustawia początkową wartość top dla gemu (...) |
Zajmiemy się teraz funkcją która będzie odpowiedzialna za sprawdzanie kolizji naszego statku. Jak taka funkcja powinna wyglądać. Wróćmy na chwilę do obrazków które przedstawiałem powyżej. Aby określić czy nasze obiekty uległy kolizji ich położenie w stosunku to Picturebox musi się w jakimś stopniu się nakładać. Pogram sam sprawdza podczas ticku jaką wartość zwraca funkcja kolizji, będzie to „True” lub „False” czyli wartość typu boolean:
1 2 3 4 5 6 7 8 9 10 |
Private Function Collision(ByVal object1 As Object) As Boolean Dim Collided As Boolean = False If object1.top + object1.height >= startposGemT And _ startposGemT + 10 >= object1.top And _ object1.left + object1.width >= startposGemL And _ startposGemL + 10 >= object1.left Then Collided = True End If Return Collided End Function |
Teraz wracamy do Timer1_Tick i wpisujemy kod:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick (...) Gemtop.Text = startposGemT.ToString 'służy do pokazania położenia top gemu Gemleft.Text = startposGemL.ToString 'służy do pokazania położenia left gemu Statekleft.Text = statek.Left.ToString 'służy do pokazania położenia left statku Statektop.Text = statek.Top.ToString 'służy do pokazania położenia top statku If Collision(statek) = True Then 'uruchamia funkcje która zwraca 1 lub 0 dla kolizji obiektów 'jeśli kolizja miała miejsce startposGemL = Int(Rnd() * (PictureBox1.Width - 2 * 10) + 10) 'nowe położenie gemu left startposGemT = Int(Rnd() * (PictureBox1.Height - 2 * 10) + 10) 'nowe położenie gemu top PictureBox1.Refresh() wynik = wynik + 1 Wynik_wartosc.Text = wynik ' dodaje 1 do wyniku End If End Sub |
Po dodaniu wszystkich elementów i kodów nasza gra powinna wyglądać tak:
Na dzisiaj tyle.
Projekt do pobrania: Sterowanie_obiektem_kolizja_obiektów
Film prezentujący program: