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

1

13.10.2005, 17:50

Kollisionsabfrage

Hallo

Ich bin gerade dabei das SDL Spiel etwas zu erweitern und wollt daher unter anderm eine Kollisionsabfrage zwischen Schiff und Asteroiden einbauen. Eigentlich kein Problem dachte ich, aber da habe ich wohl mal wieder überschätzt:

C-/C++-Quelltext

1
2
3
4
5
6
7
if(RectAsteroid.y > m_pPlayer->GetRect().y + m_pPlayer->GetRect().h &&
           RectAsteroid.y + RectAsteroid.h < m_pPlayer->GetRect().y &&
           RectAsteroid.x + RectAsteroid.w > m_pPlayer->GetRect().x &&
           RectAsteroid.x < m_pPlayer->GetRect().x +  m_pPlayer->GetRect().w)
        {
            m_bGameRun = false;
        }


Die Funktion GetRect sieht so aus:

C-/C++-Quelltext

1
2
3
4
SDL_Rect GetRect(void)
    {
        return m_pSpritePlayer->GetRect();
    }


Sie soll einfach nur das Rect des Spielers zurückgeben. Was mache ich den nur falsch?

Ich danke füe Anregungen

chrische



P.S.:

Die ganze Funktion, in der Kollisionen geprüft werden sieht folgendermaßen aus:

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
void CGame::CheckCollision(void)
{
    std::list<CShot> *ShotList = m_pPlayer->GetShotList();

    std::list<CAsteroid>::iterator ItAsteroid = m_AsteroidList.begin();
    std::list<CShot>::iterator ItShot;

    SDL_Rect RectAsteroid, RectShot;

    while(ItAsteroid != m_AsteroidList.end())
    {
        RectAsteroid = ItAsteroid->GetRect();

        for(ItShot = ShotList->begin(); ItShot != ShotList->end(); ItShot++)
        {
            RectShot = ItShot->GetRect();

            if(RectShot.y < RectAsteroid.y + RectAsteroid.h &&
               RectShot.y + RectShot.h > RectAsteroid.y &&
               RectShot.x < RectAsteroid.x + RectAsteroid.w &&
               RectShot.x + RectShot.w > RectAsteroid.x)
            {
                ItAsteroid->SetAlive(false);
                ItShot->SetAlive(false);
            }
        }
        if(ItAsteroid->IsAlive())
            ItAsteroid++;
        else
            ItAsteroid = m_AsteroidList.erase(ItAsteroid);

        //prüfen, ob Asteroid und Schiff kolidieren

        if(RectAsteroid.y > m_pPlayer->GetRect().y + m_pPlayer->GetRect().h &&
           RectAsteroid.y + RectAsteroid.h < m_pPlayer->GetRect().y &&
           RectAsteroid.x + RectAsteroid.w > m_pPlayer->GetRect().x &&
           RectAsteroid.x < m_pPlayer->GetRect().x + m_pPlayer->GetRect().w)
        {
            m_bGameRun = false;
        }
        Logfile->fTextOut("x-Wert: %d<br>",m_pPlayer->GetRect().x);
        Logfile->fTextOut("x-Wert + Breite %d<br>",m_pPlayer->GetRect().x + m_pPlayer->GetRect().w);
        Logfile->fTextOut("y-Wert: %d<br>",m_pPlayer->GetRect().y);
        Logfile->fTextOut("y-Wert + Höhe %d<br>",m_pPlayer->GetRect().y + m_pPlayer->GetRect().h);

    }

} 

chazon

Frischling

Beiträge: 56

Wohnort: Zons

  • Private Nachricht senden

2

14.10.2005, 09:46

Hi

Wenn ich das richtig sehe prüfst du folgendes:

(Ich kürze dei Rechtecke mit R und P ab )

Ry > Py+Ph => Rechteck P liegt unterhalb von R
Ry + Rh < Py => Rechteck P liegt oberhalb von R

Und das dann mit && verknüpft ???

Dann müsste -Rh > Ph sein ( Rh und Ph >0)

3

14.10.2005, 14:49

Hallo

Mit der Zeile:

Ry > Py+Ph will ich prüfen, ob die Unterkante des Asteroidenrects unterhalb der Oberkante des Schiffes ist

Mit der Zeile:

Ry + Rh < Py will ich prüfen, ob die Oberkante des Asteroiden überhalb der Unterkante des Schiffes ist.

Nur wenn beide Bedingungen erfüllt sind, treffen Sie sich doch. Vielleicht stehe ich gerade wirklich auf dem Schlauch, aber eigentlich sehe ich da keinen Fehler.

chrische

chazon

Frischling

Beiträge: 56

Wohnort: Zons

  • Private Nachricht senden

4

14.10.2005, 18:44

???

Ok . Du prüfst einmal ob der Asteroid darüber hinwegfliegt
UND
Du prüfst ob der Asteoid unter dem Raumschiff vorbeifliegt
Das geht nicht . Leicht zu sehen an der Ungleichung:

Quellcode

1
2
3
Py - Rh > Ry > Py + Ph
<=>
-Rh > Ph 


Wenn du prüfen willst ob der Astroid vorbeifliegt geht das mit einer || (oder) Verknüpfung. Also:

Quellcode

1
[(Ry > Py+Ph) || (Ry+Rh<Py)] && [(Rx > Px+Pw) ||(Rx+Rw<Px)]

(entweder drüber oder drunter) und (links oder rechts vorbei[/b])

5

14.10.2005, 23:17

Hallo

Sorry, aber es gibt anscheinende immer noch ein Verständnisproblem bei mir. Der Autor hat selber eine Kollisionsabftage zwischen Schuss und Asteroiden gemacht und diese sah folgendermaßen aus:

C-/C++-Quelltext

1
2
3
4
if(RectShot.y < RectAsteroid.y + RectAsteroid.h &&
               RectShot.y + RectShot.h > RectAsteroid.y &&
               RectShot.x < RectAsteroid.x + RectAsteroid.w &&
               RectShot.x + RectShot.w > RectAsteroid.x) 


Und genau das gleiche wollte ich auch bloss machen. Auch da sind alle Bedingngen per && verknüpft, was für mich ehrlich geasgt auch logisch klingt und aussieht. (diese Kollisionsabfrage funktioniert übrigens einwandfrei)

chrische

babelfish

Alter Hase

Beiträge: 1 222

Wohnort: Schweiz

Beruf: Informatiker

  • Private Nachricht senden

6

14.10.2005, 23:48

gehts vielleicht so?

(bin mir einfach nicht sicher, hab nur ein wenig verschoben :angel: )


C-/C++-Quelltext

1
2
3
4
if(RectAsteroid.y < m_pPlayer->GetRect().y + m_pPlayer->GetRect().h && 
           RectAsteroid.y + RectAsteroid.h > m_pPlayer->GetRect().y && 
           RectAsteroid.x > m_pPlayer->GetRect().x + m_pPlayer->GetRect().w && 
           RectAsteroid.x + RectAsteroid.w > m_pPlayer->GetRect().x)

chazon

Frischling

Beiträge: 56

Wohnort: Zons

  • Private Nachricht senden

7

15.10.2005, 09:24

Es ist ein UNterschied wenn du prüfen möchtest ob ein Objekt ein anderes trifft oder daran vorbeifliegt.

Bei einem Treffer ist der Code richtig:

Quellcode

1
2
3
4
if(RectShot.y < RectAsteroid.y + RectAsteroid.h && 
               RectShot.y + RectShot.h > RectAsteroid.y && 
               RectShot.x < RectAsteroid.x + RectAsteroid.w && 
               RectShot.x + RectShot.w > RectAsteroid.x) 


Wenn du das prüfen willst dann hast die größer/kleiner Zeichen falsch gesetzt:

Quellcode

1
2
3
4
if(RectAsteroid.y < m_pPlayer->GetRect().y + m_pPlayer->GetRect().h && 
           RectAsteroid.y + RectAsteroid.h > m_pPlayer->GetRect().y && 
           RectAsteroid.x + RectAsteroid.w > m_pPlayer->GetRect().x && 
           RectAsteroid.x < m_pPlayer->GetRect().x +  m_pPlayer->GetRect().w) 


Mit anderen Worten:
TReffer:
unter der Oberkante && über der Unterkante && rechts von der linken Seite && links von der rechten Seite

Vorbeiflug:
über der Oberkante || unter der Unterkante ||links vorbei || rechts vorbei

PS : Ich hab oben auch Blödsinn verzapft:
(entweder drüber oder drunter) und :rolleyes: (links oder rechts vorbei[/b])
ist nicht korrekt

8

15.10.2005, 21:30

Hallo

Wenn ich deine if-Abfrage einsteze, dann meldet er eine Kollision, obwohl es diese gar nicht gibt. Ich weiss echt nicht, wo das Problem liegt.

Danke für deine Hilfe

chrische

chazon

Frischling

Beiträge: 56

Wohnort: Zons

  • Private Nachricht senden

9

16.10.2005, 02:45

Die Treffer-Abfrage funktioniert nur wenn das m_pPlayer-Rechteck
kleiner ist als das Astroid-Rechteck, und sich dann innerhalb des
Astroid-Rechtecks befindet. Sie funktioniert nicht wenn das m_pPlayer-
Rechteck den Astroiden nur streift oder größer ist .
Versuch es doch einmal andersherum.
Teffer <=> ! (nicht) vorbeigeflogen

Quellcode

1
2
3
4
5
if(!(RectAsteroid.y > m_pPlayer->GetRect().y + m_pPlayer->GetRect().h ||
     RectAsteroid.y + RectAsteroid.h < m_pPlayer->GetRect().y ||
     RectAsteroid.x  > m_pPlayer->GetRect().x + m_pPlayer->GetRect().w ||
     RectAsteroid.x + RectAsteroid.w < m_pPlayer->GetRect().x))
{...}

10

16.10.2005, 10:59

Hallo


Ich danke dir sehr für deine Hilfe, aber es klappt immer noch nicht. Er springt schon in die Bedingung, bevor er einen Asteroiden berührt. Keine Ahnung, was da los ist. Ich habe mich doch an der ersten Abfrage orientiert und da klappt alles einwandfrei. Wo ist denn da der Unterschied?

chrische

Werbeanzeige