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

JRJ

Treue Seele

Beiträge: 113

Wohnort: Tirol

Beruf: Schüler

  • Private Nachricht senden

11

17.06.2011, 16:56

Sagen wir mal du hast einen vector Geschwindigkeit und einen vector Position. In jedem Frame addierst du die Geschwindigkeit zur Position. Wenn eine Kollision auftritt setzt du deine Sprite auf die Position wo die Kollision noch nicht aufgetreten ist (Position-Geschwindigkeit) und den Geschwindigkeitsvector auf 0, dann bewegt sich die Sprite nicht mehr.

12

17.06.2011, 17:37

Wie das funktioniert weiss ich auch ungefähr. Aber eigentlich wollte ich wissen wie man den Quellcode mit der SFML schreib

13

17.06.2011, 17:41

Wenn du ja weißt wie es funktioniert, dann bist du sicherlich in der Lage mit etwas Überlegen auf den Quellcode zu kommen. Das ist wirklich keine Schwierigkeit. Und wenn du was lernen willst, dann ist das auch zu empfehlen, selbst auf so etwas zu kommen.

Die SFML verfügt über die Klasse sf::Rect<T>, die ein Rechteck darstellt. Schau dir diese Klasse in der Dokumentation mal an, die sollte dir weiterhelfen.


Gruß
SaRu_

14

19.06.2011, 17:59

Danke für Die Antworten habe es nun herausgefunden ich setze nach einer Kollision den wert einfach +1 -1 usw

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Tunfisch« (19.06.2011, 18:14)


15

19.06.2011, 21:42

Ich habe doch nochmal eine Frage bezüglich Kollisonen. Mein Sprite bewegt sich immer konstant nach unten (Erdanziehungskraft bzw. Gravity) ich wollte es jetzt so einstellen das wenn mein Sprite den Boden berührt sich ein Wert auf false setzt und er nicht mehr nach unten weitergeht.

Quellcode

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
void CTilemap::Load (sf::RenderWindow &App, sf::Sprite *Player, sf::Sprite Spieler)
{
    for( int i = 0; i < map_hoehe; i++)
            {
                // alle zeilen durchlaufen
                for( int j = 0; j < map_breite; j++)
                {
                    int Sprite_WhichImage = tile [i][j];
                    int Sprite_WhichCollision = tileCollission [i][j];

                    Sprite[Sprite_WhichImage].SetPosition(j*tile_breite, i*tile_hoehe);
                    App.Draw (Sprite[Sprite_WhichImage]);

                    float ElapsedTime = App.GetFrameTime();

                    if ( Laufen == true )
                    {
                        Player->Move (0, 0.1 * ElapsedTime);
                    }

                    if ( Sprite_WhichCollision == 0)
                    {
                        if (Collision::PixelPerfectTest ( Spieler, Sprite[Sprite_WhichImage], 0 ))
                        {
                            std::cout << "false";
                            Laufen = false;

                            sf::Vector2<float> V;
                        }
                        else
                        {
                            Laufen = true;

                            std::cout << "H";
                        }
                    }
                }
    }
}


Mein Quellcode ist vielleicht nicht der beste aber er erfüllt seine funktion. Alles klappt auch eigentlich nur sendet mir die Funktion PixelPerfectTest manchmal den Wert false zurück und setzt meinen bool Wert (Laufen) wieder auf true. Und somit geht mein Sprite obwohl er auf dem Boden ist wieder nach unten und wackelt wieder.

Ausserdem handelt es sich hier nicht mehr um Pacman sondern um Mario =D.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Tunfisch« (20.06.2011, 15:03)


16

19.06.2011, 23:59

Also zunächste einmal der Hinweis: Eine pixelgenaue Kollisionserkennung für die hier genannte Situation zu verwenden ist alles andere als sinnvoll. Pixelgenaue Kollisionserkennungen sollten möglichst selten zum Einsatz kommen und nur dann wenn es nicht zu vermeiden ist. Aber schon gar nicht in jedem Frame, dann auch noch mit jedem Tile der Tilemap, nur um zu prüfen, ob die Figur auf dem Boden ist oder nicht...

Dann möchte ich noch darauf hinweisen, dass mich dein Quellcode verwirrt: Was machen Funktionsaufrufe wie Player->Move() und Collision:: PixelPerfectTest() in der Load()-Methode der Klasse CTilemap?!?! Das zeugt aber von einem mächtigen Durcheinander im Klassendesign... solltest du ganz dringend überdenken!

Warum wird die Variable Laufen sowohl bei positivem, als auch bei negativem Ausfall der Kollisionsüberprüfung auf false gesetzt? Wofür das Player->Move(0, -10.06 * ElapsedTime); ?

Gruß
SaRu_

17

20.06.2011, 15:03

Sorry eigentlich sollte bei else Laufen auf true (Z. 34 habe es schnell geändert) gesetzt werden und zweitens soll das Player Move in Zeile 28 auch nicht da sein. Ich habe ausversehen den alten Quellcode gepostet.

Zu deiner ersten Frage das Player->Move soll so etwas wie gravity sein immer wenn es keine Kollision gibt soll er konstant nach unten laufen. Es ist zwar nicht so geschickt das in der Load Funktion der Tilemap zu machen =D.

Zweitens mit welcher Überprüfung würdest du dann die Tiles auf Kollission überprüfen? Manche Tiles wie z.B. Münzen kann man ja nicht mit einer Bounding Box testen. Ich wüsste ausserdem auch gar nicht wie ich jedes Tile auf eine Kollission überprüfe wenn ich die Kollissionsüberprüfung nicht in die Load funktion meiner Tilemap setze weil es muss ja immer konstant überprüfen ob mein Sprite schon auf dem Boden ist und nicht mehr weiter nach unten schwebt.

18

20.06.2011, 19:43

Also zur Kollisionserkennung generell: Das genauste Ergebnis erhält man natürlich immer mit einer pixelperfekten Kollisionsüberprüfung, daher ja auch die Bezeichnung "pixelperfekt". Diese Methode ist jedoch viel zu langsam um häufig in einem Spiel angewendet werden zu können. Hat man jetzt z.B. eine Münze, die ja sehr wahrscheinlich rund ist, dann ist natürlich der erste Gedanke, dass eine BoundingBox in Form eines Rechtecks ja nicht zu einer kreisrunden Münze passt... Aber häufig reicht auch bei runden Objekten ein Rechteck aus - insbesondere wenn die Objekte eher klein sind im Vergleich zum Kollisionspartner (dem Spieler). Wenn jetzt aber die rechteckige Box wirklich viel zu ungenau ist, dann kann man auch hergehen und bei runden Objekten einfach einen Kollisionsradius verwenden. Man legt einen Mittelpunkt für das Objekt fest und berechnet den Abstand des Kollisionspartners zum Mittelpunkt. Ist der Abstand kleiner als der Radius des Objekts, dann liegt eine Kollision vor. Dann hat man schon einmal eine etwas genauere Überprüfung, die zwar etwas mehr Rechenzeit in Anspruch nimmt, trotzdem aber noch nicht so aufwendig ist wie eine pixelgenaue Kollisionserkennung. Es geht also immer darum eine gute Mitte zwischen Präzision und Rechenzeit zu finden. Das muss man halt austesten, je nach Spielprinzip und Form des Objektes bietet sich mal dies und mal jenes an.

Zu deinem Klassendesign: Du solltest darauf achten, dass deine Funktionen auch genau das tun, was man von ihnen erwartet, wenn man den Funktionsnamen liest. Bei CTilemap::Load() erwartet man wohl, dass eine Tilemap aus z.B. einer Datei geladen wird und das nach diesem Aufruf das Objekt dieser Klasse eine verwendbare Tilemap ist. Da gehört also keine Kollisionserkennung rein, denn solch eine Überprüfung wird regelmäßig (z.B. bei jedem Frame) im Spielverlauf aufgerufen, wohingegen die Tilemap nur zu Beginn des Spiels oder des neuen Levels geladen werden muss.

Gruß
SaRu_

19

21.06.2011, 12:28

Muss eine Tilemap nicht auch immer und immer wieder geladen werden. Also in jedem Durchlauf der Hauptschleife? Weil wenn ich die Map nur einmal lade passieren fürchterliche Dinge wie z.B. Das mein Spieler eine Spur hinterlässt das der ganze Bildschirm blinkt, usw.

Kann man eigentlich dann auch mehrere Schleifen(http://pastebin.com/AsnkafM4) von Tilemaps z.B. für verschieden grosse Tiles einsetzen oder kostet das dann zu viel perfomance.

20

21.06.2011, 12:33

Laden und Zeichnen sind zwei verschiedene Sachen.
Wenn du in jedem Frame zeichnest treten deine Probleme nicht auf, weil die "Spur" des Spielers wieder übermalt wird.
Das Laden gehört allerdings an den Anfang

MfG

Edit: Zur zweiten Frage: Warum verschieden große Tiles. Wenn du verschieden große Tiles hast ist es nicht mehr möglich einfach mal alle Tiles mit zwei Schleifen durchzugehen etc.
Wenn du größere Flächen willst, ist es am einfachsten mehrere gleiche Tiles zu verwenden

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »stoni« (21.06.2011, 12:40)


Werbeanzeige