Breakout Abprallwinkel

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Breakout Abprallwinkel

    Hallo liebe Codergemeinde!

    Ich programmiere in C++ diverse Spiele, nun versuche ich mich an einem "Breakout"-Klon, scheitere aber zusehends an einem - wahrscheinlich recht simplen - Problem.
    Ich habe eine Klasse Kugel mit folgenden Attributen:
    - Radius
    - Position (oben Links)
    - Tempo in x-Richtung
    - Tempo in y-Richtung

    Zudem habe ich eine Klasse Paddel (also der Schläger) mit folgenden Attributen:
    - Größe in x- und y- Richtung
    - Position (oben Links)

    Nun möchte ich implementieren, dass die Kugel unabhängig von ihrem aufprallwinkel in einem bestimmten Winkel abpralle: In der Mitte des Paddles senkrecht und zu den Seiten hin immer weiter gegen 45° oder sowas. Ich habe mehrere Ansätze, die Vektoraddition beinhalten und natürlich Sinus und Kosinus sowie Tangens, aber bisher nur auf dem Papier, weil sie nicht erfolgversprechend sind. Nachrechnungen mit Beispielen ergeben, dass die Kugel dann beim abprallen beschleunigt/abbremst, was nicht sinn der Sache sein soll.

    Könnt ihr mir einen - aus detailiert oder grob angedeutet - Ansatz schaffen, wie ich zum Ziel kommen kann?

    Danke im Vorraus
    Shisu
  • Hey wasserfall! Danke erstmal für deine sehr schnelle Antwort, jedoch ist das ganze noch sehr mathematisch, was du mir da zusammen geschrieben hast.

    Ich habe mich daran versucht, es in Code umzuwandeln, größtenteils funktioniert es auch, jedoch teilweise auch nicht. (Glaube ich zumindest, weil sich beim Abprallen z.B. bei einem um 180° gedrehten Paddles annomalien zeigen)
    Ein kleiner Hinweis zwischendurch: Ja, das Paddle muss auf 0, 90, 180 und 270° funktionieren, mein Breakout ist eben etwas anders.

    Hier mein Code:

    Quellcode

    1. void abprall_Ball_Paddle(Ball& pBall, const Paddle& pPaddle)
    2. { //Diese Funktion soll das Abprallen handlen, d.H. zu guter Letzt pBall mit dem richtigen ausfallwinkel belegt haben. (Der sich aus den Geschwindigkeiten ergibt)
    3. if(pBall.getPosition_Center().y < pPaddle.getPosition_Center().y)
    4. {
    5. if(pBall.getPosition_Center().x > pPaddle.getPosition_Center().x)
    6. {
    7. int lResultierende = sqrt(square(pBall.getTempo().x) + square(pBall.getTempo().y));
    8. double lWinkel = inGradmass(atan(((pPaddle.getPosition_Center().y-pBall.getPosition_Center().y)
    9. / (pBall.getPosition_Center().x-pPaddle.getPosition_Center().x))));
    10. double Tempo_x = ankathete(lWinkel, lResultierende); //cos(alpha)*hypo
    11. //DIREKT REINSCHREIBEN & FORMEL ÜBERPRÜFEN! Etwas stimmt NICHT!
    12. double Tempo_y = -gegenkathete(lWinkel, lResultierende); //sin(alpha)*hypo
    13. pBall.setTempo(sf::Vector2f(Tempo_x, Tempo_y));
    14. }
    15. else if(pBall.getPosition_Center().x < pPaddle.getPosition_Center().x)
    16. {
    17. int lResultierende = sqrt(square(pBall.getTempo().x) + square(pBall.getTempo().y));
    18. double lWinkel = inGradmass(atan(((pPaddle.getPosition_Center().x-pBall.getPosition_Center().x)
    19. / (pPaddle.getPosition_Center().y-pBall.getPosition_Center().y))));
    20. double Tempo_x = -gegenkathete(lWinkel, lResultierende); //sin(alpha)*hypo
    21. double Tempo_y = -ankathete(lWinkel, lResultierende); //cos(alpha)*hypo
    22. pBall.setTempo(sf::Vector2f(Tempo_x, Tempo_y));
    23. }
    24. else
    25. {
    26. pBall.setTempo(sf::Vector2f(0, -pBall.getTempo().y));
    27. }
    28. }
    29. else if(pBall.getPosition_Center().y > pPaddle.getPosition_Center().y)
    30. {
    31. if(pBall.getPosition_Center().x > pPaddle.getPosition_Center().x)
    32. {
    33. int lResultierende = sqrt(square(pBall.getTempo().x) + square(pBall.getTempo().y));
    34. double lWinkel = inGradmass(atan(((pBall.getPosition_Center().x-pPaddle.getPosition_Center().x)
    35. / (pBall.getPosition_Center().y-pPaddle.getPosition_Center().y))));
    36. double Tempo_x = ankathete(lWinkel, lResultierende); //cos(alpha)*hypo
    37. double Tempo_y = gegenkathete(lWinkel, lResultierende); //sin(alpha)*hypo
    38. pBall.setTempo(sf::Vector2f(Tempo_x, Tempo_y));
    39. }
    40. else if(pBall.getPosition_Center().x < pPaddle.getPosition_Center().x)
    41. {
    42. int lResultierende = sqrt(square(pBall.getTempo().x) + square(pBall.getTempo().y));
    43. double lWinkel = inGradmass(atan(((pBall.getPosition_Center().y-pPaddle.getPosition_Center().y)
    44. / (pPaddle.getPosition_Center().x-pBall.getPosition_Center().x))));
    45. double Tempo_x = -gegenkathete(lWinkel, lResultierende); //sin(alpha)*hypo
    46. double Tempo_y = ankathete(lWinkel, lResultierende); //cos(alpha)*hypo
    47. pBall.setTempo(sf::Vector2f(Tempo_x, Tempo_y));
    48. }
    49. else
    50. {
    51. pBall.setTempo(sf::Vector2f(0, -pBall.getTempo().y));
    52. }
    53. }
    54. else
    55. {
    56. pBall.setTempo(sf::Vector2f(-pBall.getTempo().x, 0));
    57. }
    58. }
    Alles anzeigen


    Hier ist von bestimmten Funktionen die Rede, ich denke, die sollten sich größtenteils selbst erklären. ("sf::Vector2f" ist eine Struktur aus SFML, sie beinhaltet einfach zwei floats.)
    Die, die ihr nicht auf Anhieb versteht, sind wohl folgende:

    Quellcode

    1. double ankathete(double pWinkel, double pHypotenuse)
    2. { //Mit dieser Formel berechne ich aus einem Winkel und der Hypotenuse dieAnkathete
    3. return cos(inBogenmass(pWinkel)) * pHypotenuse;
    4. }
    5. double gegenkathete(double pWinkel, double pHypotenuse)
    6. { //Mit dieser Formel berechne ich aus einem Winkel und der Hypotenuse die Gegenkathete
    7. return sin(inBogenmass(pWinkel)) * pHypotenuse;
    8. }
    9. double inBogenmass(double pWinkel)
    10. { //Rechnet Gradmaß in Bogenmaß um
    11. return pWinkel/180*3.1415926535;
    12. }
    13. double inGradmass(double pWinkel)
    14. { //Rechnet Bogenmaß in Gradmaß um
    15. return pWinkel*180/3.1415926535;
    16. }
    17. double square(const double x)
    18. { //gibt das Quadrat von x zurück
    19. return x * x;
    20. }
    Alles anzeigen


    Wenn ihr etwas nicht verstehen solltet, fragt bitte nach. Ich stehe euch Rede und Antwort, wenn ihr mir dafür die Annomalie erklären könnt... :)

    Danke
    Shisu
  • Nee nich closes.

    Ich denke, Du machst das (viel) zu kompliziert ?

    Physikalisch ist ja korrekt -> Einfallswinkel = Ausfallswinkel (mit der Senkrechten zur Tangente an dem Punkt als Lot - was einfach ist, wenn der Schläger eine Strecke ist) - gegeben war Position und Geschwindigkeit des Balles und Position/Größe des Schlägers.

    Man prüft also, wann (und ob) der Ball den Schläger trifft. Dann haste Dein Dreieck aus dem Lot und der Flugrichtung des Balles, was man am Lot spiegeln muss schlimmsten Falls, dann hat man die Richtung des Balles wenn er wieder abstartet ...

    Deine Idee mit den Winkeln am Rand und in der Mitte ist physikalisch so, als würde der Schläger ein Halbkreis sein - also son Hügel - nech :) - da kann man im Prinzip die gleiche Rechnung machen, da die Positionen nur wichtig für den zu erwartenden Aufprall sind und die Richtung der Geschwindigkeit Resulat eines (irgendwo stattgefundenen) Aufpralls ist.

    Also isses doch irgendwo kompliziert, aber ich meine, das ginge ohne Fallunterscheidungen - die Physik erlaubt sich sowas ja auch nicht :D - höchstens Dein Schläger ist nicht stetig differenzierbar ;)

    Edit: Spiegelung einfach, indem man den Geschwindigkeitsvektor und Lot mit einer Parallele zur Schläger-Tangenten zu einem rechtwinkligem Dreieck vervollständigt und diese künstlich erzeugte Strecke um den gleichen Betrag verlängert (neues Dreieck, mit gleichbleibendem Lot, dieser Strecke und neuem Geschwindigkeitsvektor).

    Ich würde ja ein Bild malen :-/

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von zyklo ()

  • zyklo schrieb:

    Nee nich closes.

    Wie du meinst.

    zyklo schrieb:

    Ich denke, Du machst das (viel) zu kompliziert ?

    Das habe ich nicht bestritten. Es geht mir darum, dass es funktioniert. :)

    zyklo schrieb:

    Physikalisch ist ja korrekt [...]

    Egal, ich will es ja nicht physikalisch korrekt ;)

    zyklo schrieb:

    Ich würde ja ein Bild malen :-/

    Ohne besagtes Bild verstehe ich dich leider nicht... also dass es wesentlich einfacher geht war mir klar, das ist sogut wie immer so, nur weiß ich nicht wie. Und dein Post erklärt es mir nicht hinreichend :)

    Tut mir Leid,
    Shisu