Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
Zitat von »"Koerperkarle"«
Code wäre sicher nicht unbehilflich.
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
for (It2Asteroid=m_AsteroidList.begin();It2Asteroid!=m_AsteroidList.end();It2Asteroid++) { //Prüfe ob Object aus Liste eins identisch mit Objekt aus Liste 2 //und ob Objekt bereits auf Kollision überprüft wurde if (ItAsteroid!=It2Asteroid && !ItAsteroid->Checked()) { sf::Vector2f r1=It2Asteroid->GetElement()->GetPosition(); //Ortsvektor r1 sf::Vector2f dr=r2-r1; //Abstandsvektor float dsquare=(dr.x*dr.x+dr.y*dr.y); //Abstand der Mittelpunkte zum Quadrat //Bestimmung des Quadrat der Summe der Radien float RSq=(It2Asteroid->GetElement()->GetRadius()+ItAsteroid->GetElement()->GetRadius()) *(It2Asteroid->GetElement()->GetRadius()+ItAsteroid->GetElement()->GetRadius()); //prüfe Kollisionsbedingung if (dsquare<=RSq) { // bei Kollision Berechne neue Geschwindigkeitsvektoren ItAsteroid->GetElement()->UpdateDynamics(It2Asteroid->GetElement()); // Objekt wird als kollidiert markiert It2Asteroid->SetCheck(true); } } } |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
void CElement::UpdateDynamics(CElement *pElement2) { sf::Vector2f dR=m_vPosition-pElement2->GetPosition(); sf::Vector2f V1=m_vVelocity; sf::Vector2f V2=pElement2->GetVelocity(); float m1=m_fMass; float m2=pElement2->GetMass(); float L=sqrt(dR.x*dR.x+dR.y*dR.y); // Matrix mit neuen Koordinatenachsen (parallel/senkrecht zum Stoss) float M11=dR.x/L; float M12=-dR.y/L; float M21=dR.y/L; float M22=dR.x/L; // Koordinatentransformation float Vp1=V1.x*M11+V1.y*-M12; float Vs1=V1.x*-M21+V1.y*M22; float Vp2=V2.x*M11+V2.y*-M12; float Vs2=V2.x*-M21+V2.y*M22; float Vp1_,Vp2_; // Zentraler Stoss float M=m1+m2; Vp1_=(m1-m2)/M*Vp1+2.0f*m2/M*Vp2; Vp2_=(m2-m1)/M*Vp2+2.0f*m1/M*Vp1; // Rücktransformation V1.x=Vp1_*M11+Vs1*M12; V1.y=Vp1_*M21+Vs1*M22; V2.x=Vp2_*M11+Vs2*M12; V2.y=Vp2_*M21+Vs2*M22; SetVelocity(V1); pElement2->SetVelocity(V2); } |
Zitat von »"WarMuuh!!"«
bloß ne vermutung, aber kann es sein, dass die, wenn die praktisch ineinander kleben, immer wieder kollidieren? du musst demnach verhindern, dass objekte nach der kollision sich noch berühren / überlappen
Zitat von »"babelfish"«
Entweder lässt du es gar nicht so weit kommen (Also vor dem Bewegen die Kollision überprüfen) oder du stosst sie sozusagen auseinander. Das wären mal ganz grobe Ansätze
Zitat von »"ministry"«
Ein Ansatz wäre eventuell noch, die Bewegung nur zu verhindern, wenn der Abstand der Objektmittelpunkte kleiner wird. Also, wenn sie laut der Radienüberprüfung kollidieren, lässt du sie trotzdem laufen, wenn sie "auseinander" wollen.
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
for (It2Asteroid=m_AsteroidList.begin(); It2Asteroid!=m_AsteroidList.end(); It2Asteroid++) { //Prüfe ob Object aus Liste eins identisch mit Objekt aus Liste 2 //und ob Objekt bereits auf Kollision überprüft wurde if (ItAsteroid!=It2Asteroid && !ItAsteroid->Checked()) { sf::Vector2f r1=It2Asteroid->GetElement()->GetPosition(); sf::Vector2f dr=r2-r1; // Bestimmung des Abstandes der Objekte beim naechsten Frame sf::Vector2f v1=It2Asteroid->GetElement()->GetVelocity(); sf::Vector2f v2=ItAsteroid->GetElement()->GetVelocity(); sf::Vector2f drN=dr+(v1-v2)*g_pScreen->GetFrameTime(); //Abstand der Mittelpunkte zum Quadrat im nächsten Frame; float dsquareN=(drN.x*drN.x+drN.y*drN.y); //Abstand der Mittelpunkte zum Quadrat aktuell float dsquare=(dr.x*dr.x+dr.y*dr.y); //Bestimmung des Quadrat der Summe der Radien float RSq=(It2Asteroid->GetElement()->GetRadius()+ ItAsteroid->GetElement()->GetRadius())* (It2Asteroid->GetElement()->GetRadius()+ ItAsteroid->GetElement()->GetRadius()); //prüfe Kollisionsbedingung und ob die Objekte //momentan aufeinanderzufliegen; Abstand dsquareN sollte dann //kleiner sein als der Aktuelle Abstand if (dsquare<=RSq && (dsquareN<dsquare)) { ItAsteroid->GetElement()->UpdateDynamics(It2Asteroid->GetElement()); It2Asteroid->SetCheck(true); } } } |
Werbeanzeige