Kolizja obiektów

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:

kolizja6

 

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:

kolizja7

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:

kolizja2Czas 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:

kolizja3Nie 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:

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:

    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:

    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:

    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:

    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:

kolizja8

Na dzisiaj tyle.

Projekt do pobrania: Sterowanie_obiektem_kolizja_obiektów

Film prezentujący program:

 

Permalink do tego artykułu: https://visualmonsters.cba.pl/kolizja-obiektow/

Dodaj komentarz

Twój adres email nie będzie publikowany.