• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Funkcja z parametrem dowolnego typu (SFML 2.4 Kolizje)

Object Storage Arubacloud
0 głosów
382 wizyt
pytanie zadane 1 stycznia 2017 w C i C++ przez DarkEliat Bywalec (2,810 p.)

Witam.

Piszę sobie gierkę przy użyciu zewnętrznej biblioteki SFML 2.4 i chciałem stworzy funkcję, która sprawdzałaby czy zaszła kolizja między obiektami na ekranie. Typów obiektów, które mogłyby ze sobą kolidowac jest kilka (np. Sprite, RectangleShape, CircleShape) i w tym momencie pojawia się pytanie z mojej strony czy da się stworzyc funkcję przyjmującą dowolny typ danych:

bool isCollided(Sprite obiekt1, DowolnyObiekt obiekt2);

Zdaję sobie sprawę z tego, że można stworzyc kilka wersji tej funkcji,

bool isCollided(Sprite obiket1, Sprite obiekt2); 
bool isCollided(Sprite obiekt1, RectangleShape obiekt2);

ale to skróciłoby mi kod, a zmieniając coś w funkcji robiłbym to tylko w raz, poza tym pytanie zadane z czystej ciekawości.

Pozdraiwam.

4 odpowiedzi

+1 głos
odpowiedź 1 stycznia 2017 przez criss Mędrzec (172,590 p.)
wybrane 4 stycznia 2017 przez DarkEliat
 
Najlepsza

getGlobalBounds nie jest dziedziczona z niczego, każda klasa mająca taką metode implementuje ją "na własną rękę". Więc nie - nie da sie zrobić tak jak byś chciał. Gdyby istniała klasa np. Collideable mająca wirtualną metode getGlobalBounds z której dziedziczą wszystkie klasy które powinny taką metode zawierać, to rozwiązaniem byłoby stworzenie funkcji przyjmującej referencje/wskaźniki na Collideable. Ale taka klasa nie istnieje, więc... nie.

Możesz stworzyć funkcje przyjmującą sf::FloatRect-y i w taki sposób sprawdzać kolizje między dowolnymi obiektami (podając do funkcji FloatRect-y zwrócone przez getGlobalBounds każdego z obiektów).
edit: tak jak zauważył Munvik to też niedoskonałe rozwiązanie, bo nie możesz sprawdzać kolizji okrągłymi figurami (ani w ogóle z czymkolwiek co nie zwraca sf::FloatRect).

A nie - sf::CircleShape też zwraca sf::FloatRect, więc sfml w ogóle nie oferuje kolizji z okrągłymi figurami. Musisz to sam napisać.

Możesz też opakowywać każdy ze swoich obiektów w grze we własne klasy (np. Player, Enemy itd.) dziedziczące z Collideable (również napisanej przez ciebie oczywiście) i wtedy zrobić to, co opisałem w pierwszym akapicie. Rozwiązań jest mnóstwo... :)

IMO najlepszym rozwiązaniem jest napisanie tej klasy Collideable i jakiejś klasy bazowej dla colliderów z której będą dziedziczyły np. RectangleCollider, CircleCollider itd... dzięki czemu będziesz mógł sprawdzać kolizje między czymkolwiek i ew. w razie potrzeby dopisywać kolejne klasy colliderów. Przez każdą klase Collidera rozumiem coś opakowującego sf::FloatRect czy inne napisane przez ciebie metody sprawdzania kolizji.

komentarz 1 stycznia 2017 przez DarkEliat Bywalec (2,810 p.)

Dzięki.

Ja miałem taki pomysł na tę funkcję:

bool isCollided(Sprite obiekt1, DowolnyObiekt obiekt 2) // np. RectangleShape
{
if (obiket1.intersects(obiekt2.getGlobalBounds())) return true;
else return false;
}

Sądzisz, że ten kod by zadziałał, jeśli dałoby się przesłac dowolny typ parametru do funkcji?

Pozdrawiam.

 

komentarz 1 stycznia 2017 przez criss Mędrzec (172,590 p.)

No.. tak. Ale właśnie ci tłumaczyłem, że się nie da. Nie w jednej funkcji. Możesz utworzyć template i kompilator sam utworzy potrzebne przeładowania:

template<typename T>
bool isCollided(Sprite obiekt1, T obiekt 2)
{
   return obiekt1.instersects(obiekt2);
}

 

komentarz 4 stycznia 2017 przez DarkEliat Bywalec (2,810 p.)

Bardzo dziękuję za pomoc!

Wszytko działa. Pozdrawiam smiley

komentarz 4 stycznia 2017 przez DarkEliat Bywalec (2,810 p.)

A potrafiłbyś umieścić 2 templaty w jednej funkcji? np.

bool isCollided(T object1, T object2);

albo

bool isCollided(T1 object1, T2 object2)

Jeden spokojnie przechodzi, ale przy dwóch wywala z 10 błędów.

komentarz 5 stycznia 2017 przez criss Mędrzec (172,590 p.)

Tak wyrzuca błąd? 

template<typename T1, typename T2>
bool isCollided(T1 obiekt1, T2 obiekt2);

Jaki?

komentarz 5 stycznia 2017 przez DarkEliat Bywalec (2,810 p.)
Ok, działa, ja tworzyłem tę funkcję w klasie, a tam trochę pomotałem, ale już wszystko jest ok.
+1 głos
odpowiedź 1 stycznia 2017 przez Patryk Krajewski Nałogowiec (26,170 p.)
http://www.sfml-dev.org/tutorials/2.0/graphics-transform.php scrolluj do bounding boxy i napisz funkcję na podstawie tego
komentarz 4 stycznia 2017 przez DarkEliat Bywalec (2,810 p.)
Dzięki, mądry pomysł, ale ja miałem na myśli rozwiązanie podane przez użytkownika Criss. Pozdrawiam.
+1 głos
odpowiedź 1 stycznia 2017 przez Munvik Dyskutant (9,350 p.)

Możesz wysyłać obiekt sf::FloatRect, ale poprawnie będzie działało tylko na prostokątnych figurach.

Coś takiego:

bool isCollided(sf::FloatRect objectFloatRect1, sf::FloatRect objectFloatRect2)
{
  if(objectFloatRect1.intersects(objectFloatRect2))
     return true;

   return false;
}

A kolizja z kołem to już druga funkcja, no chyba że wyślesz też sf::FloatRect koła bo się da :D

komentarz 4 stycznia 2017 przez DarkEliat Bywalec (2,810 p.)
Dzięki, mądry pomysł, ale ja miałem na myśli rozwiązanie podane przez użytkownika Criss. Pozdrawiam.
0 głosów
odpowiedź 23 kwietnia 2017 przez Gankkah Użytkownik (720 p.)

Użyj szablonów:

template </*PARAMETRY*/>
/*TYP_ZWRACANEGO_OBIEKTU NAZWA_FUNKCJI*/(/*ARGUMENTY*/)
{
      //CIAŁO FUNKCJI
}

Więc nagłówek funkcji będzie taki:

template <class typ>
bool isCollided(Sprite obiekt1, typ obiekt2)
{
     //CIAŁO FUNKCJI
}

 

komentarz 23 kwietnia 2017 przez draghan VIP (106,230 p.)
Proszę o zapoznanie się z punktem II 3. Regulaminu.

Podobne pytania

0 głosów
1 odpowiedź 173 wizyt
pytanie zadane 17 marca 2019 w C i C++ przez Filipotyk Obywatel (1,280 p.)
0 głosów
0 odpowiedzi 253 wizyt
pytanie zadane 19 czerwca 2022 w C i C++ przez hicodyn Początkujący (420 p.)
0 głosów
0 odpowiedzi 109 wizyt
pytanie zadane 6 września 2020 w C i C++ przez NieMaJuzNazw Użytkownik (890 p.)

92,568 zapytań

141,420 odpowiedzi

319,618 komentarzy

61,954 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...