qest43 Temat założony przez niniejszego użytkownika |
[SFML2] Platformówka a bounding box collision » 2015-06-21 15:32:23 Piszę platformówkę, mam taki system kolizji gdzie wyliczam położenie lewo,prawo,górę,dół od gracza i klocków, potem jeśli kolizja występuję przypisuję odpowiednie położenie: if( player.getSize().intersects( sprite.getGlobalBounds() ) ) { float bottom = sprite.getPosition().y + sprite.getGlobalBounds().height; float left = sprite.getPosition().x; float right = sprite.getPosition().x + sprite.getGlobalBounds().width; float top = sprite.getPosition().y; float pBottom = player.getPosition().y + player.getSize().height; float pLeft = player.getPosition().x; float pRight = player.getPosition().x + player.getSize().width; float pTop = player.getPosition().y; float prevBottom = player.getPrevPosition().y + player.getSize().height; float prevLeft = player.getPrevPosition().x; float prevRight = player.getPrevPosition().x + player.getSize().width; float prevTop = player.getPrevPosition().y; if( pBottom >= top ) { sf::Vector2f newPosition; newPosition.x = player.getPosition().x; newPosition.y = top - 0.1 - player.getSize().height; player.setPosition( newPosition ); } else if( pTop <= bottom ) { sf::Vector2f newPosition; newPosition.x = player.getPosition().x; newPosition.y = bottom; player.setPosition( newPosition ); } else if( pRight >= left ) { sf::Vector2f newPosition; newPosition.x = left - 0.1 - player.getSize().width; newPosition.y = player.getPosition().y; player.setPosition( newPosition ); } else if( pLeft <= right ) { sf::Vector2f newPosition; newPosition.x = right; newPosition.y = player.getPosition().y; player.setPosition( newPosition ); }
Problem polega na tym że jak kolizja powinna wystąpić po bokach -lewego lub prawego boku to teleportuje na górę klocka. Szukam rozwiązania tego problemu, bo potrzebuję taki system kolizji żeby też działało przy ruchomych platformach. Znacie jakieś rozwiązanie? |
|
pekfos |
» 2015-06-21 16:50:01 Najpierw sprawdzaj, jakiego rodzaju jest kolizja (w pionie, poziomie), a potem dopiero sprawdzaj konkretny kierunek. |
|
qest43 Temat założony przez niniejszego użytkownika |
» 2015-06-21 17:04:01 Ale na postać zawsze działa grawitacja więc trzeba sprawdzać w pionie. |
|
Lora |
» 2015-06-21 17:21:20 To ci źle działa przez te else if-y. Co się stanie jeśli spełnione są warunki pBottom >= top i pRight >= left naraz? Wykona się tylko działanie dla tego pierwszego warunku i cofnie gracza do góry jednocześnie przesuwając go w poziomie na nową pozycję: if( pBottom >= top ) { sf::Vector2f newPosition; newPosition.x = player.getPosition().x; newPosition.y = top - 0.1 - player.getSize().height; player.setPosition( newPosition ); }
|
|
qest43 Temat założony przez niniejszego użytkownika |
» 2015-06-21 17:27:35 Dla każdego klocka sprawdza z osobna, nie ma takie możliwości żeby pBottom >= top było TRUE i pRight >= left też TRUE, bo jak jest na samej górze to po prawej może już być tylko inny klocek, a z nowym klockiem już się sprawdzi kolizję osobno. |
|
pekfos |
» 2015-06-21 17:37:01 nie ma takie możliwości żeby pBottom >= top było TRUE i pRight >= left też TRUE |
Jest możliwe i tego typu przypadki wywołują błąd, który próbujesz rozwiązać. Ale na postać zawsze działa grawitacja więc trzeba sprawdzać w pionie. |
Nie. |
|
Lora |
» 2015-06-21 17:41:17 Nie wiem jak wygląda struktura twojej gry więc ciężko powiedzieć, ale wydaje mi się, że mam rację. Załóżmy, że bounding box gracza ma parametry: sf::Rect < float >( 52, 50, 30, 30 ) , a bounding box jakiegoś klocka po prawej: sf::Rect < float >( 85, 50, 50, 30 ) . Klikasz strzałkę w prawo i przesuwasz gracza np. o 5 pikseli w prawo. Teraz mamy: pBottom = 80, pRight = 87, top = 50, left = 85. Sprawdzamy kolizję: if( pBottom >= top ) - Prawda no to wykonujemy działanie: newPosition.x = player.getPosition().x = 57 newPosition.y = top - 0.1 - player.getSize().height = 19.9 // Poprzednia pozycja była równa 50! Wynik - teleportacja. A warunek( pRight >= left ) też jest prawdą ale się nie wykona, bo jest po elsie. |
|
pekfos |
» 2015-06-21 17:53:04 Oblicz rozmiar części wspólnej bounding boxa platformy i postaci gracza. Jeśli jest szersza, niż wyższa, to zderzenie nastąpiło z góry lub z dołu, w przeciwnym wypadku było z boku. Dla każdego z tych dwóch przypadków sprawdzasz tylko konkretny kierunek i teleportujesz postać do odpowiedniej krawędzi. Dodatkowo, jeśli nie ma żadnej kolizji, to wyjdą ci zera w rozmiarze części wspólnej, więc możesz tym zastąpić także główny warunek player.getSize().intersects(sprite.getGlobalBounds()). |
|
« 1 » 2 3 |