[C/C++] Pong - Flugrichtung und dazu passende Fluggeschwindigkeit

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von Flyde, 8. Juni 2010 .

Schlagworte:
  1. 8. Juni 2010
    Pong - Flugrichtung und dazu passende Fluggeschwindigkeit

    Hiho,

    hab heute mal angefangen mein erstes Game mit dem SFML SDK zu schreiben, funzt echt prima.. hocke schon begeisternd (suchtend) locker 7-8 stunden an Pong Aber hab gerade ein kleines problem was dringend gelöst werden muss...

    Hier mal der Code für den fixen überblick, geht um die Bewegung des Balles bei Pong
    Code:
    // bl = Ball
    // pl = Player
    // Angle = Winkel
    // Speed = Geschwindigkeit des Balls
    // Position des jeweiligen objektes (bl / pl)
    
    CBall::CBall()
    {
     blAngle.x = 0.05.f; // Winkel x
     blAngle.y = 0.05.f; // Winkel y
     blSpeed = 1.1f; // Ballgeschwindigkeit, noch nicht implementiert
    }
    
    
    // plPosition ist ein struct (plPosition.x plPosition.y) und übergibt die aktuelle Position des Spielers (im Hauptprogramm wird errechnet ob es der obere oder untere ist)
    // ElapsedTime ist die Zeit, die es für den neuen Frame gebraucht hat, damit ich das ganze auf eine Einheitliche FPS bekomme 
    void CBall::MoveBall(sf::Vector2f plPosition, float ElapsedTime)
    {
     blPosition.x = blPosition.x + blAngle.x;
     blPosition.y = blPosition.y + blAngle.y;
    
     // Ball hits left wall / hits right wall
     if(blPosition.x <= 0 || blPosition.x >= 800-20) // 20 = ballsize
     {
     blAngle.x = blAngle.x * -1;
     }
     // Ball hits top-player / hits bottom-player (hier ist noch viel Hard-Coding.. sind die oberen und unteren Ränder aber auch nicht weiter entscheidend für mein Problem)
     if((blPosition.y <= 35 || blPosition.y >= 600-57) && (blPosition.x >= plPosition.x && blPosition.x <= plPosition.x+72 ))
     {
     blAngle.y = blAngle.y * -1;
     }
     
     // Bewegt den Ball
     blSprite.Move(blAngle.x, blAngle.y);
    }

    Das Problem ist meine Rechnung..
    Code:
    blPosition.x = blPosition.x + blAngle.x;
    blPosition.y = blPosition.y + blAngle.y;
    ...
    blAngle.x = blAngle.x * -1;
    ...
    blAngle.y = blAngle.y * -1;
    
    das mit dem Winkel funktioniert soweit.. aber leider beeinflusst es auch die geschwindigkeit weil man einen Winkel nun mal beschissen in px angeben kann

    Ich würde gerne eine vernünftige formel dafür aufbringen, in der die ElapsedTime berücksichtigt wurde und gleichzeitig die Geschwindigkeit blSpeed mit einbezieht
     
  2. 8. Juni 2010
    AW: Pong - Flugrichtung und dazu passende Fluggeschwindigkeit

    Du meinst wohl es beeinflusst z.Z. nicht die Geschwindigkeit und es soll Geschiwndigekeitsabhängig sein.

    ....

    Als erster würd ich die Variable blAngle anderst nennen und zwar blDirection o.ä da es ein Vektor ist der die Richtung angibt und der Winkel dadruch festgellegt ist, desweiteren würd ich alle gespeicherten Werte relativ zum Einheitsvektor angeben (Werte zwischen 0..1) und mit blSpeed (Werte zwischen 1 und ~200) die Geschwindigkeit angeben und die Multiplikation mit diesem Skalar im endeffekt dein Geschwindigkeitsvektor representiert.

    ...

    Zum Berechnen der neuen Position

    Aktuelle/Neue Position (plPosition) = p
    Richtungsvektor (blDirection) = r
    Geschwindigkeit (blSpeed) = v
    Verstrichene Zeit (ElapsedTime[in ms]) = t
    Verschiebungsvektor = d

    Die Formel wäre dann:
    Code:
    1. d = v * r (= Verschiebung pro 1s)
    2. d = d/ 1000 * t (= Verschiebung pro verstrichene Zeit t)
    3. p = p + d
    4. Abfrage ob Koordinaten gültigen und ob eine Kollosion erfolgt ist um eine Richtungsänderung durchzuführen 
    Wobei man die Punkte 3 bis 4 möglichst in viele Berrechnungsdruchgänge verteilen sollte um eine genaure "physikalischen" Effekt zu erzielen, dh den Verschiebungsvektor nur auf eine ms berechnen und in einer Schleife bis zur ElapsedTime den Vektor addieren und bei diesen Anweisung jedesmal prüfen ob ein Richtungswechsel erforderlcih ist, welcher durch Kollison oder was auch immer verursacht wurde.

    Mfg Rushh0ur
     
  3. 8. Juni 2010
    AW: Pong - Flugrichtung und dazu passende Fluggeschwindigkeit

    Puh ich seh den ball garnicht mehr.. wenn ich die Bewegung auskommentier dann steht er still also vermute ich das er sich über der sichtbaren geschwindigkeit bewegt und dann aus dem bildschirm schießt

    Finde auch den Fehler auf anhieb nicht oO

    Auch punkt 3 macht für mich nicht so viel sinn weil bei jedem Frame die aktuelle neue Position des spielers übertragen wird, eher müsste man die Ballposition neu berechnen.. aber geht beides nicht

    Ball.cpp
    Code:
    CBall::CBall()
    {
     blDirection.x = 0.5f;
     blDirection.y = 0.3f;
     blSpeed = 50.f;
    }
    
    sf::Vector2f CBall::GetBallDisplacement()
    {
     return blDisplacement;
    }
    
    void CBall::MoveBall(sf::Vector2f plPosition, float ElapsedTime)
    {
     blDisplacement.x = blSpeed * blDirection.x;
     blDisplacement.y = blSpeed * blDirection.y;
    
     blDisplacement.x = blDisplacement.x / (1000*ElapsedTime);
     blDisplacement.y = blDisplacement.y / (1000*ElapsedTime);
     
     // Neue Position des Balles
     blPosition.x = blPosition.x + blDisplacement.x;
     blPosition.y = blPosition.y + blDisplacement.y;
     
     // Ball hits left wall / hits right wall
     if(blPosition.x <= 0 || blPosition.x >= 800-20) // 20 = ballsize
     {
     blDisplacement.x = blDisplacement.x * -1;
     }
     /*
     // Ball hits top-player / hits bottom-player
     if((blPosition.y <= 35 || blPosition.y >= 600-57) && (blPosition.x >= plPosition.x && blPosition.x <= plPosition.x+72 )) // 20 = ballsize
     {
     blDisplacement.y = blDisplacement.y * -1;
     }*/
    
     blSprite.Move(blDisplacement.x, blDisplacement.y);
    }
    Main.cpp
    Code:
     // Check if the ball is out
     if(!Game.CheckFieldOut(Ball.GetBallPosition())) 
     {
     // Wenn sich y richtung positiv bewegt -> Prüfe die Kollision mit Pl1 (Ball bewegt sich anch unten)
     // Wenn sich y richtung negativ bewegt -> Prüfe die Kollision mit Pl2 (Ball bewegt sich nach oben)
     if(Ball.GetBallDisplacement().y >= 0) Ball.MoveBall(Pl1.GetPosition(), ElapsedTime);
     else Ball.MoveBall(Pl2.GetPosition(), ElapsedTime);
     }
     
  4. 8. Juni 2010
    AW: Pong - Flugrichtung und dazu passende Fluggeschwindigkeit

    Die Werte der if Abfragen werden bei dir am Anfang der Funktion immer wieder neu berechnet und somit nicht übernommen; hab mal den Code angepasst:

    PHP:
    void CBall :: MoveBall ( sf :: Vector2f plPosition float ElapsedTime )
    {
        
    int i ;

        
    // Bewegungsschleife (ElapsedTime in msec)
        
    for ( i = 0 i < ElapsedTime ; ++ i )
        {
          
    // Geschwindigkeitsvektor (pixel/msec)
          
    blDisplacement . blSpeed  blDirection . 1000 ;
          
    blDisplacement . blSpeed  blDirection . 1000 ;

          
    // Neue Position des Balles
          
    blPosition . blPosition . blDisplacement . x ;
          
    blPosition . blPosition . blDisplacement . y ;

          
    // Kollisionen ermitteln
        
           // Ball hits left wall / hits right wall
           
    if( blPosition . <=  ||  blPosition . >=  800 - 20 // 20 = ballsize
              
    blDirection . blDirection . * (- 1 );

           
    // Ball hits top-player / hits bottom-player
           
    if(( blPosition . <=  35  ||  blPosition . >=  600 - 57 ) && ( blPosition . >=  plPosition . &&  blPosition . <=  plPosition . x + 72  ))  // 20 = ballsize
              
    blDirection . blDirection . * (- 1 );

           
    // ..... Weitere Kollisionen Prüfen
           // Je nach Kollisionsart kann der Richtungsvektor und damit der Winkel verändert werden
           // -> Verhältnis zwischen blDirection.x und blDirection.y
           // Genauso kann auch nach einer Kollision die Geschwindigkeit verringert oder erhöht werden
        
    }

        
    // Ball verschieben und Rendern
        
    blSprite . Move ( blPosition . x blPosition . y );
    }

    Mfg Rushh0ur
     
  5. 8. Juni 2010
    AW: Pong - Flugrichtung und dazu passende Fluggeschwindigkeit

    die for-schleife wird doch nie länger als 1x durchlaufen, oder? o.0 elapsedtime müsste irgendwas mit 0.00XX sein weil das ja die zeit ist, die der letzte frame gebraucht hat..

    Mal was anderes, ich seh immer noch keinen ball...
    Ich habs mal getestet, es muss immer noch irgendwas an der Formel falsch sein , denn wenn ich

    Code:
    blSprite.Move(0.5f, 0.00f);
    fix setze, dann seh ich wieder die ball bewegung..
    Mal schauen, ich spiel jetzt noch mal n wenig rum evtl fällt dir die lösung ja noch ein ansonsten werd ich mich jetzt mal drum kümmern zahlen ausgespuckt zu bekommen (evtl hat die engine ja n log-system wo ich die zahlen raushauen kann)

    edit: okay es lag an einem missverständnis... du hast die neue ball position errechnet und ich hatte versucht die ballbewegung zu errechnen...

    einmal .Move durch .SetPosition ersetzt und schon gehts
     
  6. 8. Juni 2010
    AW: Pong - Flugrichtung und dazu passende Fluggeschwindigkeit

    Kommt drauf an wie schnell bei dir die Bilder gerendert werden, ein Spiel welches mit min 60 FPS läuft ist in Ordnung. Wenn deins nun mehr schaft solltest du eventuell mal die CPU/GPU-Power schonenen und die Frames drosseln, die restliche Performance kann man immer gut für andere Dinge benutzen.

    Musst ja beachten, dass wenn du das Spiel nicht drosselst und bei dir es super Funktioniert, kann es passieren das es auf einem anderem Computer entweder zu schnell oder zu langsam läuft, deswegen eine for schleife damit eine annähernd gleiche Spielgeschwindigkeit erzielt wird.

    Bei dir ist die Renderzeit pro Bild ein vielfaches kleiner als 1ms dh. das Spiel läuft bei dir extrem schnell was du wahrscheinlich durch einen anderen blSpeed zu regeln versucht hast.

    Das Problem was sich auf einem langsarem Rechner festellen wird ist, dass die Renderzeit bei diesem zwar auch vl. unter 1ms liegt trotzdem langsamer erscheint. Da sollte die Renderzeit schon mehr als eine millisekunde Betragen um eine Gleichgewicht durch die for schleife zu erhalten.

    Mfg Rushh0ur
     
  7. 9. Juni 2010
    AW: Pong - Flugrichtung und dazu passende Fluggeschwindigkeit

    danke erst mal für die infos, also das mit den verschiedenen fps wusste ich, bei der bewegung der spieler wurde das mit: x-bewegung * elapsedtime gefixed..

    Wenn ich die FPS auf 60 force, läuft alles normal, bei 100 läuft es wie bei 60.. aber wenn ich 20 einstelle, bewegen sich die spieler immer noch so schnell wie bei 60 (da werden frames übersprungen und man sieht keine flüssige bewegung) nur der ball wird langsamer (bewegt sich langsam flüssig)

    bei den spielern wurde es durch x-bewegung * elapsed time gefixed.. das ganze hatten wir ja eigentlich auch in der formel, wundert mich, dass das nicht klappt oO

    EDIT:
    damit gefixed ^^ läuft mit 20, 60 und 100 fps konstant
    -----

    noch was anderes

    um das ganze realistischer zu machen, macht es sinn eine weitere bewegungsaddition durchzuführen?

    Meine Idee: X-Bewegung des spielers, z.b. -0.5px/frame und diese kraft der seitwärtsbewegung auf die kugel zu übertragen, sinnvoll?

    im übrigen war ich noch nie n physik und mathe fan aber sobald man es mal praktisch brauch fasziniert es einfach nur
     
  8. 11. Juni 2010
    AW: Pong - Flugrichtung und dazu passende Fluggeschwindigkeit

    Das ist durchaus eine gute Idee, die auch so praktiziert wird. Physikalisch wird durch die Reibung ein Drehimpuls übertragen und ja nach Richtung und Geschwindigkeit wird der Ball in die Richtung mal stärker, mal schwächer abgelenkt und nicht stehts symetrisch "reflektiert".

    Sonst würde sich ja die Richtung niemals ändern, wenn der Ball senkrecht zur Fläche auftreffen würde (Bei einem Rechteckigen Raum).

    Entweder du machst es wie du gesagt hast mit einem konstanten Wert, oder wenn du mehr herausforderung überwinden möchtest, dann berechnestes du die Geschwindigkeit, die dein "Balken" hat und "lenkst" die Kugle / das Objekt demnach ab.
    Das könnte man relativ einfach realiesieren in dem man periodisch beim gedrückt halten einer Teste eine Variable, welche ein Mass für die Ablenkung darstellt, hochzählt/runterzählt (Richtung?) und beim loslassen, also im unbewegten Zustand, wieder auf Null setzen.

    Mfg Rushh0ur
     
  9. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.