SFML kolizje - moja mini biblioteka

0

Jeśli ktoś ma problemy ze sprawdzaniem kolizji w sfml to polecam sobie zobaczyć ;) Działa prawie dla wszystkich nieregularnych kształtów. Jestem otwarty na opinie, oceny, rady, wskazówki i konstruktywną krytykę.

https://github.com/10kw10/Perfect-collision

PS. ma jedną wadę, ale myślę, że nie zauważycie ;d

PPS. wcale nie pisze w CB, ale nie raz trzeba i proszę się nie śmiać z mojego tutoriala xd

1
b = -begin.y * (end.x - begin.x) - (begin.y - end.y) * begin.x;

Można to zamienić na:

b = -begin.y * end.x + end.y * begin.x;
0

Trudny ten kod...I piszę to na serio!!

2
  1. nie ma sensu uzywac new https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete/
  2. Colliders nie ma sensu i uwalniasz pamiec ktora nie nalezy do Ciebie wiec masz tam UB
  3. uzywaj listy inicjalizacyjnej
2

@10kw10: wywal z readme.md link do mediafire, w zamian dołączając plik wykonywalny do repozytorium.


Jedna rzecz mnie zastanawia – dlaczego te collidery wewnątrz metod control sprawdzają stan klawiszy? IMO takie dane powinieneś dostarczyć w argumentach – albo stan klawiszy, albo już gotowe, obliczone na ich podstawie offsety.

Ja tam za bardzo w gamedevie nie siedzę, ale z tego co rozumiem, collidery są silnie uzależnione od klawiatury. Jeśli zajdzie potrzeba sterowania obiektami z poziomu kodu (czyli np. przez AI), to trzeba będzie modyfikować stan klawiszy, aby ten kod w ogóle dało się zastosować, co jest gigantycznym ograniczeniem.

0

@10kw10: no dobrze, w takim razie załóżmy, że mamy dwa okrągłe obiekty sterowane przez AI i jeden okrągły przez gracza. Jak będzie wyglądało sprawdzenie kolizji tych trzech obiektów?

Pomińmy na razie hardkodowane wartości offsetów i kątów rotacji (sic!).

0

kazdy z kazdym, okregi akurat bardzo latwo sprawdzic, sprawdzamy odleglosc srodkow i porownujemy do sumy promieni

0

To jest akurat czysta matematyka – mnie interesuje to, które obiekty wywołają ObjectWithCircleCollider::control(). Jeśli więcej niż jeden, to masz poważny błąd projektowy.

0

nie mam zadnego bledu projektowego ;d chyba, to sa osobne obiekty wiec kazdy ma oddzielna metode ;d
w main.cpp

ObjectWithCircleCollider *p1 = new ObjectWithCircleCollider();
// i dalej
p1->control();

i tak dla kazdego obiektu osobno.

0

Każdy z tych trzech obiektów wywoła tę samą metodę – bo metoda jest jedna, przyspawana do klasy, operująca na innych danych zawartych w polach. Co za tym idzie, każdy z tych trzech obiektów wywoła metodę, która je przesunie na podstawie stanu klawiatury i wykona detekcję kolizji.

Podsumowując – każdy obiekt sprawdza stan wciśniętych klawiszy, a nie tylko ten, którym steruje gracz. Prawda?

0

ty chyba piszesz w jakims htmlu lub cssie bez obrazy oczywiscie ;d

prosty przyklad (nie wiem czemu akurat taki mi przyszedl na mysl)
ty ruszasz reka i ja ruszam reka, ruszamy ta sama reka? Razem jestesmy obiektami tej samej klasy: czlowiek

0
10kw10 napisał(a):

ty chyba piszesz w jakims htmlu lub cssie bez obrazy oczywiscie ;d

Jeśli masz w ten sposób odpowiadać i obrażać mnie wyłącznie dlatego, że cierpliwie w sposób rzeczowy i kulturalny próbuję wytknąć Ci oczywisty błąd projektowy, to może w ogóle nie odpowiadaj i tkwij sobie nadal w przekonaniu, że Twój kod jest wspaniały.

Powodzenia.

0

dobra, teraz zrozumialem xd tak mi bylo najwygodniej sprawdzac kolzije, jesli samemu sie poruszam tymi obiektami. Ta klasa jest tylko do testow. Skoro chcialem napisac wykrywanie kolziji to nie chcialem dodatkowo pisac AI itp
Nie mialem zamiaru Cie obrazic, po prostu zle zrozumialem pytanie, sorry ;p

0

Nie musisz pisać AI, żeby potwierdzić moje przypuszczenia. Bo jeśli są stosowne, to wystarczy stworzyć dwa obiekty i spróbować poruszać jednym z nich. Jeśli przy wciskaniu klawiszy poruszą się oba, to otrzymasz jawny dowód, że ten kod jest błędy i nie da się go zastosować w żadnym projekcie. No chyba że w takiej grze, w której jest jeden obiekt.

0

Ok, to znaczy ze nie ogladales dokladnie kodu, a na pewno opusciles ten fragment w main.cpp

p1->up = sf::Keyboard::W;
p1->down = sf::Keyboard::S;
p1->left = sf::Keyboard::A;
p1->right = sf::Keyboard::D;
p1->rotateLeft = sf::Keyboard::Q;
p1->rotateRight = sf::Keyboard::E;

p2->up = sf::Keyboard::Up;
p2->down = sf::Keyboard::Down;
p2->left = sf::Keyboard::Left;
p2->right = sf::Keyboard::Right;
p2->rotateLeft = sf::Keyboard::Period;
p2->rotateRight = sf::Keyboard::Comma;

p3->up = sf::Keyboard::T;
p3->down = sf::Keyboard::G;
p3->left = sf::Keyboard::F;
p3->right = sf::Keyboard::H;
p3->rotateLeft = sf::Keyboard::V;
p3->rotateRight = sf::Keyboard::B;
0

Kod z braku czasu przeglądnąłem pobieżnie i tak – to mi umknęło. Jednak w dalszym ciągu jest kilka problemów.

Collider nie powinien zajmować się logiką dotyczącą inputu. Ma on od biedy wziąć dwa obiekty i je ze sobą stuknąć – aktualizując ich pozycję, kąt, prędkość itd. Te dane powinny być dostarczone colliderowi, zamiast wysysać je z palca. Łamiesz zasadę pojedynczej odpowiedzialności, niepotrzebnie komplikując kod i wprowadzając do niego niepotrzebne zależności (obiekt->klawiatura->kolizja).

Po drugie, implementujesz logikę inputu we wszystkich obiektach, nawet tych z inputem niepowiązanych. Co zrobisz, jeśli w danym teście zapragniesz stworzyć małe środowisko z wieloma martwymi obiektami (np. budynkami) i obiektem sterowanym przez gracza? Graczowi przypiszesz konkretne klawisze, a budynkom jakieś zerowe klawisze? Kolizja obiektu gracza z budynkiem wymaga sprawdzenia pozycji, kształtów, kątów i prędkości, a nie stanu klawiatury. To samo tyczy się obiektów sterowanych przez AI – im też trzeba będzie przypisać jakieś klawisze, zerowe/nullowe, jak zwał tak zwał.


Masz oczywisty błąd projektowy i zrozum to w końcu. Aby Twój kod miał sens, musisz rozdzielić logikę kolizji od sprawdzania inputu – koniec kropka.

Każdy obiekt mogący wchodzić w interakcję (tu: zderzać się) z innymi obiektami powinien posiadać dane dotyczące swojej pozycji i kształtu. Każdy obiekt mogący być poruszanym po ekranie, powinien dodatkowo posiadać dane dotyczące kierunku ruchu i prędkości. I to wszystko nie ma nic wspólnego z inputem.

Natomiast sam collider powinien być w stanie przeprowadzić zderzenie na podstawie instancji dowolnych obiektów opisanych w poprzednim paragrafie. Dla przykładu dwóch – przekazujesz dwie instancje do collidera, ten przeprowadza kolizję na podstawie danych zawartych w tych obiektach oraz odpowiednio je modyfikuje.

Logika inputu powinna się znajdować w innej klasie.

0

Kompletnie mnie nie zrozumiales, czemu caly kod uwazasz jakby sie go juz nie dalo zmienic?

Collider nie powinien zajmować się logiką dotyczącą inputu.

Collider sie tym nie zajmuje. Klasa nazywa sie

ObjectWithCircle/PolygonCollider

przez to rozumiem np. Car, ktory bd mial atrybut Circle/PolygonCollider

Pomysliles klase ObjectWith... z Collider, w tym tkwi problem.

powiem ci nawet wiecej, samochod tez nie bd mial sprawdzania klawiszy, bd mial Player, ktory bd dziedziczyl po IObject, czyli inteligentym obiekcie

0

W dalszym ciągu pozostaje kwestia sprawdzania inputu w nieodpowiednim miejscu – to trzeba odseparować.

1

przeciez to tylko dla testow jest, do projektu i tak wezme tylko folder 'Collider'. Ty juz chyba sobie ze mnie zarty robisz ;d

0

Testy też wypadałoby pisać z sensem, skoro pokazujesz je publicznie – nie każdy wie, że pisałeś je byle jak.

1 użytkowników online, w tym zalogowanych: 0, gości: 1