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

Jawaiica

Treue Seele

  • »Jawaiica« ist der Autor dieses Themas

Beiträge: 134

Wohnort: Hannover

Beruf: Student

  • Private Nachricht senden

1

11.06.2011, 13:10

[C++ & SFML] Collisionsproblem! >.<

Hallo Leute,

ich musste leider eine kleine Pause einlegen beim Programmieren und habe gestern wieder angefangen. Nun musste ich feststellen, dass ich bevor ich aufgehört habe ein Problem mit einer Kollision hatte. Und zwar habe ich mir eine "map" gemacht, in der ich ein viereckiges Gold Bild platziert habe und eine Person die man mit W, A, S, D steuern kann.
Leider weiß ich jetzt nicht wie ich es hin bekommen kann, dass die Figur geblockt wird, wenn sie gegen eine der Seiten geht. Ich habe schon ein wenig rumprobiert aber nichts hat geklappt!

Könnt ihr mir vielleicht helfen?


MfG Jawaiica'
"Die Sekunde ist die Dauer von 9 192 631 770 Perioden der Strahlung, die dem Übergang zwischen den beiden Hyperfeinstrukturniveaus des Grundzustandes des Atoms Caesium 133 entspricht."

2

11.06.2011, 13:39

Wenn du eine TileMap hast, dann gibst du jedem Tile eine Eigenschaft wie z.B. bool bSolid. Ist die Eigenschaft true, so kann das Feld nicht betreten werden, ist es false geht es.

Bewegt sich deine Figur immer um ganze Felder, dann brauchst du bei einer Bewegung lediglich prüfen, ob das Feld, wo die Figur sich hinbewegen soll begehbar ist und falls nein, dann führst du einfach keine Bewegung aus.

Bewegt sich deine Figur aber nicht "feldweise" sondern auch mal nur um ein halbes Feld, dann brauchst du in der Tat eine Kollisionserkennung. Dabei kontrollierst du einfach ob das sf::Rect des Tiles das sf::Rect der Spielfigur überlappt. (Es gibt da die Methode intersects() ) Falls ja, dann prüfst du wieder die Eigenschaft des Tiles ob es begehbar ist, wenn nicht, dann setzt du halt die Koordinaten der Spielfigur so, dass sie vor dem entsprechenden Tile stoppt.

Gruß
SaRu_

Jawaiica

Treue Seele

  • »Jawaiica« ist der Autor dieses Themas

Beiträge: 134

Wohnort: Hannover

Beruf: Student

  • Private Nachricht senden

3

13.06.2011, 02:15

Danke für die Antwort, aber ich weiß leider nicht, wie ich das jetzt genau machen soll >.< hast du vielleicht ein gutes Tutorial für sf::rect? Ich finde da irgendwie keins, gearbeitet habe ich damit bisher auch nicht wirklich mit der SFML.
"Die Sekunde ist die Dauer von 9 192 631 770 Perioden der Strahlung, die dem Übergang zwischen den beiden Hyperfeinstrukturniveaus des Grundzustandes des Atoms Caesium 133 entspricht."

valentin

Treue Seele

Beiträge: 212

Wohnort: Schweiz

Beruf: Schüler

  • Private Nachricht senden

4

13.06.2011, 12:27

Das is zwar kein Tutorial, aber im Prinzip sollte das reichen: http://www.sfml-dev.org/documentation/1.…ssf_1_1Rect.php
visit me on deviantArt!
http://v-alentin.deviantart.com/

There is no programming language, no matter how structured, that will prevent programmers from making bad programs. //Larry Flon

Jawaiica

Treue Seele

  • »Jawaiica« ist der Autor dieses Themas

Beiträge: 134

Wohnort: Hannover

Beruf: Student

  • Private Nachricht senden

5

13.06.2011, 16:41

Vielen dank! Nur ich verstehe leider immer noch nicht genau, wie ich das anwenden soll.

Muss ich das dann so machen:
sf::Rect Player1(???);
sf::Rect Gold(???);


Was genau kommt denn in die Klammern? Ich weiß nur, dass Left Right Top Bottom da rein kommen, aber jede Seite hat doch 2 Koordinaten oder net? :D
und dann?
"Die Sekunde ist die Dauer von 9 192 631 770 Perioden der Strahlung, die dem Übergang zwischen den beiden Hyperfeinstrukturniveaus des Grundzustandes des Atoms Caesium 133 entspricht."

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

6

13.06.2011, 17:09

Koordinaten der linken, oberen Ecke sowie die Größe (Breite, Höhe) deines Rechtecks.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Jawaiica

Treue Seele

  • »Jawaiica« ist der Autor dieses Themas

Beiträge: 134

Wohnort: Hannover

Beruf: Student

  • Private Nachricht senden

7

13.06.2011, 17:15

Ok, das hab ich jetzt versucht: sf::Rect Spieler1(100,100,200,200);
doch dann kommen immer zwei Fehler:

Zitat

missing template arguments before 'Spieler1'
und
expected ';' before 'Spieler1'|
achja und include:

Zitat

#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Graphics/Rect.hpp>
#include <SFML/Window.hpp>
"Die Sekunde ist die Dauer von 9 192 631 770 Perioden der Strahlung, die dem Übergang zwischen den beiden Hyperfeinstrukturniveaus des Grundzustandes des Atoms Caesium 133 entspricht."

valentin

Treue Seele

Beiträge: 212

Wohnort: Schweiz

Beruf: Schüler

  • Private Nachricht senden

8

13.06.2011, 17:30

Das Ganze muss entweder so

C-/C++-Quelltext

1
sf::Rect<int> test(100,100,200,200);

oder so

C-/C++-Quelltext

1
sf::IntRect test(100,100,200,200);

aussehen.

Wenn du das ganze allerdings mit float oder doubles willst, kannst du das int einfach dadurch austauschen. sf::DoubleRect existiert jedoch nicht, da musst du das erste anwenden. (Da das ein Template ist.)
visit me on deviantArt!
http://v-alentin.deviantart.com/

There is no programming language, no matter how structured, that will prevent programmers from making bad programs. //Larry Flon

Jawaiica

Treue Seele

  • »Jawaiica« ist der Autor dieses Themas

Beiträge: 134

Wohnort: Hannover

Beruf: Student

  • Private Nachricht senden

9

13.06.2011, 17:38

ach so funktioniert das. Natürlich >.< Vielen dank ich werde es gleich mal ausprobieren!

edit:
ok das funktioniert schon einmal! Danke noch einmal :) nur wie funktioniert das jetzt mit Intersects?^^

Zitat

if(Spieler1.Intersects(Gold1, NULL) == true)
{
xPlayer = 50;
yPlayer = 50;
}
so funktioniert es jedenfalls nicht

Es muss irgendwie hier dran liegen:

C-/C++-Quelltext

1
sf::Rect<float> Spieler1(xPlayer, yPlayer, Player.GetWidth(), Player.GetHeight());        sf::Rect<float> Gold1(xGold, yGold, Gold.GetWidth(), Gold.GetHeight());



denn wenn ich abfrage, ob es falsch ist, dann bleibt die Figur konstant auf 50, 50 stehen.
"Die Sekunde ist die Dauer von 9 192 631 770 Perioden der Strahlung, die dem Übergang zwischen den beiden Hyperfeinstrukturniveaus des Grundzustandes des Atoms Caesium 133 entspricht."

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »Jawaiica« (13.06.2011, 17:57)


10

13.06.2011, 18:30

Im Grunde ist das schon richtig wie du das machst:

C-/C++-Quelltext

1
2
3
4
if(Spieler1.Intersects(Gold1))
{
     // Kollision! 
}


Du musst dir jetzt nur überlegen, was du machen willst, wenn Spieler und Gold kollidieren. Also z.B. das Gold aufsammeln, dann könntest du einfach das Gold-Objekt löschen und dem Spieler dafür Punkte geben. Oder wenn der Spieler da nicht drüber- bzw. durchlaufen kann, dann musst du entsprechend die Koordinaten zurücksetzen. Wenn er abprallen soll, dann die Bewegungsrichtung umkehren.

Wenn du willst, dass der Spieler stehn bleibt und nicht weiterlaufen kann, dann musst du wissen, aus welcher Richtung der Spieler kommt und dann kannst du den Spieler dementsprechend in die Richtung wieder zurücksetzen.


*EDIT*:

Hab mich gerade mal hingesetzt und versucht dir das grafisch etwas zu verdeutlichen. Vielleicht hilft dir das eher...

Du bewegst deine Spielfigur eigentlich immer entlang einer Bewegungsrichtung. Bei einem 2D-Spiel wird die durch einen 2-dimensionalen Vektor angegeben, der die Bewegung in eine x- und eine y-Komponente aufteilt: V.x und V.y
Stellst du jetzt fest, dass eine Kollision vorliegt, so kannst du ermitteln, wie weit die Spielfigur das Kollisionsobjekt überlappt. (Bei der SFML kann man dafür als zweiten, optionalen Parameter der Intersects()-Methode einen Zeiger auf ein Rect-Objekt übergeben, das dann nach dem Funktionsaufruf genau so breit und hoch ist, wie die Überschneidung der beiden geprüften Rects) In meinem Beispiel ist der x-Wert, also wie weit die Spielfigur das Kollisionsobjekt in x-Richtung überlappt, der kleinere Wert. Daher korrigiere ich die Position der Spielfigur so, dass sie gerade so vor dem Kollisionsobjekt liegt. Also entgegengesetzt dem Bewegungsvektor. Wenn der also einen negativen Wert hat, dann plus, andernfalls minus. Jetzt muss nur noch der y-Wert der Spielfigur angepasst werden. Diese Korrektur ergibt sich aus dem x-Wert multipliziert mit der y-Komponente des Bewegungsvektors und geteilt durch dessen x-Komponente. Fertig!


(Link)




Gruß
SaRu_

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »SaRu« (13.06.2011, 19:28)


Werbeanzeige