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

11

24.08.2013, 20:19

Jo pascht schon. Bringt dich so aber nicht wirklich weiter.
Das Problem, wie erwähnt, ist eben, dass du gleich nach Erfüllung einer Bedingung von insgesamt vier Bedingungen, die für eine Kollision zwischen zwei Rechtecken erfüllt sein müssen, meinst, dass eine Kollision stattfand.

C-/C++-Quelltext

1
2
3
4
if(/*Kollisionsbedingungen*/)
{
    //bisheriger Code, der zur Lokalisierung dient
}

Die Kollisionsbedingungen wurden ja vom Tom aka LetsGameDev schön aufgelistet:
1. Linke Seite von A < Rechte Seite von B
2. Rechte Seite von A > Linke Seite von B
3. Obere Seite von A < Untere Seite von B
4. Untere Seite von A > Obere Seite von B

MfG
Check

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Checkmateing« (24.08.2013, 20:25)


Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

12

24.08.2013, 20:32

Ich wollte nur klar stellen, dass ich das wenigstens richtig verstanden habe.

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

13

24.08.2013, 22:43

Hab jetzt hinbekommen das es ne Kollision erkennt (endlich :D) hab ich nur euch zu verdanken :thumbsup:.
Hier der 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
void CStartGame::m_bCheckCollision (CSprite Sprite)
{


    double dLeftA, dLeftB;
    double dRightA, dRightB;
    double dTopA, dTopB;
    double dBottomA, dBottomB;
    
    dLeftA = Sprite.fXPos;
    dRightA = Sprite.fXPos + Sprite.GetWith();
    dTopA = Sprite.fYPos;
    dBottomA = Sprite.fYPos + Sprite.GetHeight();

    it = Fields.begin();

    while ( it != Fields.end() )
    {

        
        dLeftB = it->XPos;
        dRightB = it->XPos + it->GetWith();
        dTopB = it->YPos;
        dBottomB = it->YPos + it->GetHeight();
    
        if( dLeftA < dLeftB &&
            dRightA > dLeftB &&
            dTopA < dBottomB &&
            dBottomA > dTopB )
            cout << "Kollision!" << endl;

    it++;

    }
}


Hab nur leider keinen Plan wie ich das mit den einzelnen Seiten hinbekommen soll ?( .

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Swoerm« (25.08.2013, 17:14)


Beiträge: 25

Beruf: Schüler

  • Private Nachricht senden

14

25.08.2013, 17:18

Das mit den einzelen Seiten könntest du (ich habs nicht getestet) überprüfen ,indem du das wie folgst machst :
1. Schau nach ob überhaupt eine Kollision statt findet (wie in deinem Letzten Quellcode-ausschnitt)
2. Wenn du eine Kollision hast ,dann schaust du von welcher Seite das andere Objekt anstößt.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if(Kollision) {
   if(Kollision links) {
   //
   }
   else if(Kollision rechts) {
   //
   }
   else if(Kollision oben) {
   //
   }
   else if (Kollision unten) {
   //
   }
}



Bevor ich dir eine komplette Lösung hinschreib ,vielleicht kommst auch drauf ,wenn du dir mal die Bildchen hier anschaust ;) . Die Bennennung der Ecken solltest du ja wissen :D
Ich hoffe das ist nicht zu verwirrend :o

MfG
»MuesliSchuessel« hat folgendes Bild angehängt:
  • Unbenannt.png

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

15

25.08.2013, 17:57

Ich hab irgendwo ein Verständnisproblem.
Bei dem ersten Bild oben links ist ja die rechte Seite von B kleiner als die linke von A.
Deshalb müsste ja die Abfrage so aussehen:

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
while ( it != Fields.end() )
    {
        bCollision = false;
        
        dLeftB = it->XPos;
        dRightB = it->XPos + it->GetWith();
        dTopB = it->YPos;
        dBottomB = it->YPos + it->GetHeight();
    
        if( dLeftA < dRightB &&
            dRightA > dLeftB &&
            dTopA < dBottomB &&
            dBottomA > dTopB )
            bCollision = true;

        if(bCollision)
        {
        if(dRightB < dLeftA)
        {
            m_bCollisionLeft = true;
        }
        }


EDIT: Sie funktioniert aber nicht.

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Swoerm« (25.08.2013, 18:54)


16

25.08.2013, 19:08

Wie auch? :pillepalle:
Du prüfst vorher genau das Gegenteil.

MfG
Check

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

17

25.08.2013, 19:58

Das ist so ziemlich das dümmste was ich je programmiert habe... :dash:
Ich hab's korrigiert und das selbe noch für alle anderen Richtungen eingebaut, jetzt erkennt es eine Kollision lässt den Spieler stoppen aber ab diesem Punkt kann er sich in keine andere Richtung mehr bewegen.

Hier der 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
void CStartGame::ProcessMoving ()
{

    m_bCollisionLeft = false;
    m_bCollisionRight = false;
    m_bCollisionTop = false;
    m_bCollisionBottom = false;


    m_bCheckCollision (Player);

    if( g_pFramework->KeyDown (SDLK_LEFT)  && Player.fXPos > 0 && !m_bCollisionLeft )
    {
    Player.fXPos -= PlayerSpeed;
    PlayerState = Left;

    }

    if( g_pFramework->KeyDown (SDLK_RIGHT) && Player.fXPos + Player.Sprite->w < g_pFramework->m_pScreen->w && !m_bCollisionRight )
    {
    Player.fXPos += PlayerSpeed;
    PlayerState = Right;
    }

    if( g_pFramework->KeyDown (SDLK_UP) && Player.fYPos > 0 && !m_bCollisionTop )
    {
        Player.fYPos -= PlayerSpeed;
        PlayerState = Up;
    }

    if( g_pFramework->KeyDown (SDLK_DOWN) && Player.fYPos + Player.Sprite->h < g_pFramework->m_pScreen->h && !m_bCollisionBottom )
    {
        Player.fYPos += PlayerSpeed;
        PlayerState = Down;
    }

}


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
void CStartGame::m_bCheckCollision (CSprite Sprite)
{


    double dLeftA, dLeftB;
    double dRightA, dRightB;
    double dTopA, dTopB;
    double dBottomA, dBottomB;

    bool bCollision = false;
    
    dLeftA = Sprite.fXPos;
    dRightA = Sprite.fXPos + Sprite.GetWith();
    dTopA = Sprite.fYPos;
    dBottomA = Sprite.fYPos + Sprite.GetHeight();

    it = Fields.begin();
    
    while ( it != Fields.end() )
    {
        bCollision = false;
        
        dLeftB = it->XPos;
        dRightB = it->XPos + it->GetWith();
        dTopB = it->YPos;
        dBottomB = it->YPos + it->GetHeight();

        if( dLeftA < dRightB &&
            dRightA > dLeftB &&
            dTopA < dBottomB &&
            dBottomA > dTopB )
            bCollision = true;

        if(bCollision)
        {

        if(dLeftA < dRightB)
            m_bCollisionLeft = true;

        if( dRightA > dLeftB )
            m_bCollisionRight = true;

        if( dTopA < dBottomB )
            m_bCollisionTop = true;

        if( dBottomA > dTopB )
            m_bCollisionBottom = true;

        }

        it++;
    }
}

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

18

25.08.2013, 20:17

Du solltest dein CSprite auch nicht unbedingt per value an die checkCollision übergeben... ;) Per (konstanter) Referenz wäre klüger.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

19

25.08.2013, 20:29

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        if(bCollision)
        {

        if(dLeftA < dRightB)
            m_bCollisionLeft = true;

        if( dRightA > dLeftB )
            m_bCollisionRight = true;

        if( dTopA < dBottomB )
            m_bCollisionTop = true;

        if( dBottomA > dTopB )
            m_bCollisionBottom = true;

        }

Ist Käse, da ist für jede normale Kollision alles true. Schau mal in die if-Bedingung für eine Kollision. Jetzt guckst du dir die vier Bedingungen an. Findet eine Kollision statt, wird zwangsweise jeder Boolean da auf true gesetzt, da du dort nur einzeln die Sätze nochmal abprüfst, was wenig Sinn macht. Du musst das noch einschränken.

MfG
Check

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

20

25.08.2013, 21:11

Ich weiß nicht wie ich das was du beschreibst umsetzten sollte. Ich kann ja nicht nach der ersten zutreffenden Bedingung die Schleife verlassen da es ja sein kann das Pacman an bis zu 3 Ecken gleichzeitig stößt.

Es könnte aber auch sein das ich heute mit dem falschen Fuß aufgestanden bin da ich heute schon jede Menge Unsinn programmiert habe.

Edit: Anders gesagt: Ich bin langsam verzweifelt und es wäre schön wenn jemand das letzte fehlende Stückchen Code liefern könnte. (Ich glaub anders begreife ich es nicht)

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Swoerm« (25.08.2013, 23:14)


Werbeanzeige