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

15.08.2011, 15:53

Probleme mit Kollisionserkennung

Hallo
Nachdem ich das Buch C++ für Spieleprogrammierer durchgearbeitet habe, versuch ich mich jetzt an einem eigenen kleinen Spiel mit der SDL. Es soll ein tilebasiertes Spiel ähnlich wie Super Mario werden (mit Schwerkraft, also man fällt die ganze Zeit). Bis jetzt lief die Entwicklung soweit eigentlich ganz gut, doch nun habe ich ein Problem mit der Kollisionserkennung.
Hier ist der bisherige 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
for (ItTile = TileList->begin ();
             ItTile != TileList->end  ();
             ++ItTile)
        {
            if (ItTile->IsSolid () == true)
            {

                // Rects holen
                RectTile = ItTile->GetRect ();
                RectPlayer = m_pPlayer->GetRect ();

                // Überschneiden sich die Rects?
                if ((RectTile.y < RectPlayer.y + RectPlayer.h) &&
                    (RectTile.y + RectTile.h > RectPlayer.y) &&
                    (RectTile.x < RectPlayer.x + RectPlayer.w) &&
                    (RectTile.x + RectTile.w > RectPlayer.x))
                {
                    m_pPlayer->MoveBack ();
                }
            }
        }


Bei der Funktion MoveBack () wird der Spieler einfach an die Position zurück gesetzt an der er als letztes war. Im Prinzip funktioniert das auch soweit (man kann sich zumindest nicht mehr durch irgendwelche Tiles durchbewegen).
Allerdings gibt es dabei nun folgendes Problem:
Wenn der Spieler sozusagen auf einem Tile "liegt", dann kann man sich nicht nach links und rechts bewegen (man kann sich also gar nicht mehr bewegen)
und wenn der Spieler ein Tile von der Seite berührt hört er auf zu fallen und hängt sozusagen an dem Tile.
Woher dieses Problem kommt ist ja eigentlich klar: Auch wenn der Spieler sich nur auf einem Tile befindet, findet eine Kollision statt -> Der Spieler wird immer wieder an seine alte Position zurückgesetzt-> Er kann sich nicht mehr bewegen
Allerdings habe ich keine Ahnung wie ich diesen Fehler beheben kann :/
Ich hoffe ihr könnt mir helfen
MfG R4yZz0r

Sc4v

Alter Hase

Beiträge: 376

Beruf: Student

  • Private Nachricht senden

2

15.08.2011, 17:02

Ich hatte es damals so gelöst, dass ich nicht überprüft habe ob es derzeit eine Kollision gibt, sondern ob es in Zukunft eine gibt. Falls nein habe ich die Figur weiter bewegen lassen.
Ich weiß aber nicht ob das die Beste Lösung ist xD

lg

derolli

Treue Seele

Beiträge: 144

Beruf: Student

  • Private Nachricht senden

3

15.08.2011, 17:04

Du könntest versuchen die Seite, die kollidiert
herauszufinden und dann nur diese Bewegungsrichtung
zurücksetzen.

4

15.08.2011, 17:15

Du könntest versuchen die Seite, die kollidiert
herauszufinden und dann nur diese Bewegungsrichtung
zurücksetzen.

Das habe ich mir auch schon überlegt nur leider habe ich es bis jetzt noch nicht hingekriegt die Seite herauszufinden :D
Wenn du eine Idee hast, wie man das machen kann, dann kannst du sie mir ja schreiben :)

Zitat von »Sc4v«

Ich hatte es damals so gelöst, dass ich nicht überprüft habe ob es derzeit eine Kollision gibt, sondern ob es in Zukunft eine gibt. Falls nein habe ich die Figur weiter bewegen lassen.
Ich weiß aber nicht ob das die Beste Lösung ist xD

lg


Sehr interessante Idee! Das werde ich definitiv mal probieren. Ich glaube das wird dann meine Notlösung sein :D Danke :)

Sc4v

Alter Hase

Beiträge: 376

Beruf: Student

  • Private Nachricht senden

5

15.08.2011, 17:19

die Seite die kollidiert müsste man doch eigentlich durch die Bewegungsrichtung der Figur herausfinden können.
Fällt die Figur nach unten ist die kollidierende Seite die untere (bzw obere des kollidierten Objekts)... bewegt sich die Figur nach rechts ist es die rechte(linke) Seite

6

15.08.2011, 18:19

die Seite die kollidiert müsste man doch eigentlich durch die Bewegungsrichtung der Figur herausfinden können.
Fällt die Figur nach unten ist die kollidierende Seite die untere (bzw obere des kollidierten Objekts)... bewegt sich die Figur nach rechts ist es die rechte(linke) Seite


Klar das wäre möglich, nur bei mir ist halt das Problem, dass es Schwerkraft gibt, also dass man durchgehend fällt. Wenn ich also eine Variable habe, in der ich die Richtung speichere, dann beinhaltet diese immer die Richtung unten.
Ich könnte jetzt zwar eine Variable erstellen, die nur die Richtung links oder rechts beinhaltet und die Y-Koordinate standardmäßig immer bei einer Kollision zurücksetzen. Nur dann gibt es ebenfalls das Problem, dass man festhängt sobald man eine Wand berührt.

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

7

15.08.2011, 18:29

Mach es doch mit 'nem Vector, dann brauchst du keine zwei Variablen. Y bleibt dank Schwerkraft immer negativ, x ändert sich je nach Seite.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

8

15.08.2011, 23:48

Mach es doch mit 'nem Vector, dann brauchst du keine zwei Variablen. Y bleibt dank Schwerkraft immer negativ, x ändert sich je nach Seite.

Ja aber ich wüsste nicht wie das das Problem mit der Kollisionserkennung funktionieren sollte. Weil es müsste ja trotzdem erkannt werden, ob der Y-Wert des Vectors auf 0 gesetzt werden muss, damit der Spieler nicht weiterfällt, wenn er z.B. auf einem Block fällt.
Tut mir Leid wenn ich dich falsch verstehe.
Danke übrigends für die vielen, schnellen Antworten ! :)

mfG R4yZz0r

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

9

16.08.2011, 01:12

Ich meinte den Vector nur für den Sturz bzw. Schwerkraft.

C-/C++-Quelltext

1
if (rect.y >= (rectPlayer.y + rectPlayer.h) + abs(vec.y)) { // Kollision mit dem nächsten Punkt

Und dann vec.y = 0;

Bei den Seiten Kollisionen müsste man dann nur noch die x Werte testen und ebenfalls vec.x hinzunehmen, um den Punkt zu finden, der eine Iteration weiter erreicht wird.
Sollte es zu einer Kollision mit der Seite kommen, dann könnte du den Spieler abprallen lassen (ggf. mit einer geringen Verletzung für das tangieren der Wand), so würde der Spieler nicht "hängen" bleiben.
Und mit der obigen Kollisionserkennung sollte eig. auch nicht der Fall auftreten, dass du nicht mehr nach rechts oder links kannst, denn du wirst durch die Überprüfung des nächsten Schrittes niemals in ein Rect "hineinsacken".
Oder missverstehe ich dich?
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

10

16.08.2011, 17:59

Ich meinte den Vector nur für den Sturz bzw. Schwerkraft.

C-/C++-Quelltext

1
if (rect.y >= (rectPlayer.y + rectPlayer.h) + abs(vec.y)) { // Kollision mit dem nächsten Punkt

Und dann vec.y = 0;

Bei den Seiten Kollisionen müsste man dann nur noch die x Werte testen und ebenfalls vec.x hinzunehmen, um den Punkt zu finden, der eine Iteration weiter erreicht wird.
Sollte es zu einer Kollision mit der Seite kommen, dann könnte du den Spieler abprallen lassen (ggf. mit einer geringen Verletzung für das tangieren der Wand), so würde der Spieler nicht "hängen" bleiben.
Und mit der obigen Kollisionserkennung sollte eig. auch nicht der Fall auftreten, dass du nicht mehr nach rechts oder links kannst, denn du wirst durch die Überprüfung des nächsten Schrittes niemals in ein Rect "hineinsacken".
Oder missverstehe ich dich?


Vielen vielen Dank ! :) Es funktioniert jetzt perfekt !
Danke auch nochmal an alle anderen für die vielen Antworten :)
mfG R4yZz0r

Werbeanzeige