Du bist nicht angemeldet.

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

Preakz

Frischling

  • »Preakz« ist der Autor dieses Themas

Beiträge: 30

Wohnort: NRW

  • Private Nachricht senden

1

12.02.2013, 16:27

Ping Pong Kollision

Hallo Liebe Community,
ich hab da ein Problem...

und zwar geht es um mein Ping Pong was ich in C++ mit der SMFL programmiert habe. Es funktionier alles soweit bis auf die Abprallrichtung :(

Hier mal mein code:

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
void Pongball::RenderBall(float FPS, sf::RenderWindow &window, bool *running, Pongbalken balken[])
{
    if( *running == true)
    {
        float x = sprite.getPosition().x;
        float y = sprite.getPosition().y;

        cout << "winkel: "<< winkel << endl;



        if( y-ballhöhe <= 0 ) //wände prüfen
        {
             winkel= 180-winkel;
        }
        if( y+ballhöhe >= window.getSize().y)
        {
             winkel = 180-winkel;
        }


        if( RectOverlap( balken[0].sprite.getPosition().x, balken[0].sprite.getPosition().y, balken[0].BalkenWeite, balken[0].BalkenHöhe, sprite.getPosition().x, sprite.getPosition().y, ballweite, ballhöhe ) == true ) //Spieler1 colli prüfen (links)
        {
             winkel=360-winkel;
             float abweichung=2*(balken[0].sprite.getPosition().x-x);
             winkel=winkel-abweichung;
        }
        if( RectOverlap( balken[1].sprite.getPosition().x, balken[1].sprite.getPosition().y, balken[1].BalkenWeite, balken[1].BalkenHöhe, sprite.getPosition().x, sprite.getPosition().y, ballweite, ballhöhe ) == true ) //Spieler2 colli prüfen (rechts)
        {
            winkel=360-winkel;
            float abweichung=2*(balken[0].sprite.getPosition().x-x);
            winkel=winkel+abweichung;
        }

        if( winkel > 360 )
            winkel = winkel - 360;
        if( winkel < 0 )
            winkel = winkel + 360;



    
        if( x < 0+ ballweite )
        {
            cout << "Player 2 hat einen Punkt gemacht (:"<<endl;
            addpoints(2);
            (*running) = false;
            sprite.setPosition(window.getSize().x/2-ballweite, window.getSize().y/2-ballhöhe);
            winkel = zufall( 315, 225 );
        }
        else if ( x > window.getSize().x-ballweite )
        {
            cout << "Player 1 hat einen Punkt gemacht (:"<<endl;
            addpoints(1);
            (*running) = false;
            sprite.setPosition(window.getSize().x/2-ballweite, window.getSize().y/2-ballhöhe);
            winkel = zufall( 105, 45 );
        }
        else
        {
            x = x + (cos(winkel)*speed)*FPS;
            y = y - (sin(winkel)*speed)*FPS;
            sprite.setPosition(x, y);
        }
        sprite.setOrigin(15.0f,15.0f);
        sprite.rotate(20);
        window.draw(sprite);
    }
    else
    {
        sprite.setOrigin(15.0f,15.0f);
        sprite.rotate(20);
        window.draw(sprite);
    }
}


PS: Die Balken befinden sich Links und Rechts, die Wände Oben und unten.

Ich hoffe mir kann da jemand einen Denkschub geben :)
Mit freundlichen Grüßen
Preakz

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

12.02.2013, 17:25

Ich würde gar nicht mit Winkeln arbeiten, sondern die x- und y-Komponente der Bewegungsrichtung separat speichern.
Abprallen ist dann trivial: einfach das Vorzeichen von x- oder y-Komponente umkehren.

Preakz

Frischling

  • »Preakz« ist der Autor dieses Themas

Beiträge: 30

Wohnort: NRW

  • Private Nachricht senden

3

12.02.2013, 17:47

Ich würd's aber schon lieber mit winkeln machen damit der Ball ein bisschen Abwechslungsreicherer Flugbahnen hat.

4

12.02.2013, 18:09

Das heißt du magst wirklich die Physik ignorieren? (Einfallswinkel = Ausfallswinkel)

MfG
Check

Preakz

Frischling

  • »Preakz« ist der Autor dieses Themas

Beiträge: 30

Wohnort: NRW

  • Private Nachricht senden

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

12.02.2013, 18:52

Das heißt du magst wirklich die Physik ignorieren? (Einfallswinkel = Ausfallswinkel)

MfG
Check

Ist das nicht bei Pong und Brick genau Absicht? Je näher ein Ball der Ecke des Reflektors kommt, desto mehr ändert sich sein Ausfallswinkel. Oder man denke an angeschnittene Bälle. Im ersten Original von Pong kam nichts davon vor, in den späteren Varianten aber durchaus.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dreat

Frischling

Beiträge: 86

Wohnort: Heilbronn

  • Private Nachricht senden

7

12.02.2013, 19:49

Also ich bastel selbst gerade ein Pong mit der SFML und hab die Bewegung grade mal zum testen so hingeklatscht ohne Kollisionen.

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
if( m_fPos.x >= 752 )   
bLeftRight = true; 

if( m_fPos.x <= 32 )    
bLeftRight = false;

if( bLeftRight )
Ball.Move( -m_fSpeed, 0 );

else
Ball.Move( m_fSpeed, 0 );

if( m_fPos.y >= 568 )
bUpDown = true;

if( m_fPos.y <= 32 )    
bUpDown = false;

if( bUpDown )
Ball.Move( 0, -m_fSpeed );

else
Ball.Move( 0, m_fSpeed );

m_fPos = Ball.GetPosition();


m_fSpeed ist auf 0.05 gesetzt wird auch noch nicht erhöht, heißt der Ball wird nicht schneller.

Preakz

Frischling

  • »Preakz« ist der Autor dieses Themas

Beiträge: 30

Wohnort: NRW

  • Private Nachricht senden

8

12.02.2013, 20:25

Also ich habs jetzt einfach so simple gemacht. Auch wenn ichs gerne anders gehabt hätte (:

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
void Pongball::RenderBall(float FPS, sf::RenderWindow &window, bool *running, Pongbalken balken[])
{
    string s;
    s = to_string(P1Punkte);
    s += ":";
    s += to_string(P2Punkte);
    text.setPosition(window.getSize().x/2-10, 60 );
    text.setString(s);



    if( *running == true)
    {
        float x = sprite.getPosition().x;
        float y = sprite.getPosition().y;

        



        if( y-ballhöhe < 0 )
        {
             yspd = -yspd;
             xspd = xspd;
        }
        if( y+ballhöhe > window.getSize().y)
        {
             yspd = -yspd;
             xspd = xspd;
            
        }

        if( RectOverlap( balken[0].sprite.getPosition().x, balken[0].sprite.getPosition().y, balken[0].BalkenWeite, balken[0].BalkenHöhe, sprite.getPosition().x, sprite.getPosition().y, ballweite, ballhöhe ) == true )
        {
            if(yspd > 0 && xspd > 0)
                yspd = -yspd;

             xspd = -xspd;
        }
        if( RectOverlap( balken[1].sprite.getPosition().x, balken[1].sprite.getPosition().y, balken[1].BalkenWeite, balken[1].BalkenHöhe, sprite.getPosition().x, sprite.getPosition().y, ballweite, ballhöhe ) == true )
        {
            if(yspd < 0 && xspd < 0)
                yspd = -yspd;

             xspd = -xspd;
        }




    
        if( x < 0)
        {
            cout << "Player 2 hat einen Punkt gemacht (:"<<endl;
            addpoints(2);
            (*running) = false;
            sprite.setPosition(window.getSize().x/2-ballweite, window.getSize().y/2-ballhöhe);
            xspd = -0.6f;
            yspd = 0.6f;

        }
        else if ( x > window.getSize().x-ballweite )
        {
            cout << "Player 1 hat einen Punkt gemacht (:"<<endl;
            addpoints(1);
            (*running) = false;
            sprite.setPosition(window.getSize().x/2-ballweite, window.getSize().y/2-ballhöhe);
            xspd = -0.6f;
            yspd = -0.6f;
            
        }
        else
        {
            x = x + xspd*FPS;
            y = y + yspd*FPS;
            sprite.setPosition(x, y);
        }
        sprite.setOrigin(15.0f,15.0f);
        sprite.rotate(20);
        window.draw(sprite);
        window.draw(text);
    }
    else
    {
        sprite.setOrigin(15.0f,15.0f);
        sprite.rotate(20);
        window.draw(sprite);
        window.draw(text);
    }
}

9

13.02.2013, 00:29

Zitat von dir "Auch wenn ichs gerne anders gehabt hätte (:"

vy = v * sin(w);
vx = v * cos(w);

v ist die konstante Geschwindigkeit vom Ball.
Wenn nun der Ball gegen den Balken knallt kannst du so die komponenten vx, vy neu berechnen.
Musst nur überlegen, w (in RAD) so zu wählen, das der Ball nicht nach hinten wegfliegt.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

10

13.02.2013, 08:47

Ich würd's aber schon lieber mit winkeln machen damit der Ball ein bisschen Abwechslungsreicherer Flugbahnen hat.

Das ist aber kein Argument gegen "meinen" Ansatz, das kannst du damit ebenfalls hinkriegen.

Werbeanzeige