Hilfe bei Kollision in meinem Spiel
-
Hallo,
kann mir jemand dabei helfen die Kollision in meinem Test Game hinzubekommen?
Also die Anfangsdate sind:
Viereckige Spielfigur dessen jede Seite 10 lang ist.
der Spieler kann sich in allen vier Richtungen bewegen.
dazu hat er 2 Variablen (BeschleunugungX und BeschleunigungY) die durch Tastatur abfragen der Pfeiltasten um je 1 erhöht werden(wird dann immer am ende zurückgesetzt.).
eine Reihe von 10*10 großen Blöcken (benannt mit Umgebung[X]) stehen auf der Fläche.
Probiert hab ich schon das ich die Alte Position speicher, die Kollision mit der neuen Position teste und bei einer Kollision die Position des Spielers zurücksetze.
Fehler der entsteht: wenn der Spieler sich an das Objekt "drückt" (bsp Objekt rechts Spieler links und User drückt Pfeil nach rechts) und er dazu nach oben will geht das nicht den der Spieler wird immer zurückgesetzt.auch ein Versuch war es immer eine Kollision Prüfen wenn der User eine Tastatur abfrage macht und nur wenn er nicht kollidiert kann er sich bewegen.
Problem: wenn der Spieler sich nicht durch eine Tastatur abfrage bewegt wir keine Kollision getestet.
-
wenn der Spieler sich an das Objekt "drückt" (bsp Objekt rechts Spieler links und User drückt Pfeil nach rechts) und er dazu nach oben will geht das nicht den der Spieler wird immer zurückgesetzt.
Also ich habe es mir jetzt mal aufgezeichnet um halbwegs nachzuvollziehen was dein Problem ist. Wohin transformierst du die deine 10*10-Figur denn, wenn sie kollidiert? Könntest du mal den entsprechenden Code zeigen? Was ich machen würde: Jeder seite der Box Instanzen zuweisen um später feststellen zu können ob du an einer vertikalen oder mit einer horizontalen Seite kollidiert bist. Je nachdem könntest du die Figur dann einfach nur auf einer Ebene (x oder y) wegtransformieren.
auch ein Versuch war es immer eine Kollision Prüfen wenn der User eine Tastatur abfrage macht und nur wenn er nicht kollidiert kann er sich bewegen.
Problem: wenn der Spieler sich nicht durch eine Tastatur abfrage bewegt wir keine Kollision getestet.Das ist Quatsch. Das macht man nicht. Man checkt einfach die Transformationskoordinaten aller Objekte und nicht erst dann, wenn man was in die Tastatur eingibt. Das wäre viel zu umständlich, außerdem würde es dann massenhafte Spielefehler geben.
-
leider bin ich noch nicht so recht bewandert in c++ deshalb köntest du das mit den "Jede seite der Box Instanzen zuweisen" etwas genauer erklären?
und der code sieht jetzt so aus:
ich benutze sfml
das ist die Funktion mit der ich Kollisionen prüfe:
int IsCollided(const sf::Sprite& First, const sf::Sprite& Second) { sf::Vector2f FirstPosition1 = First.GetPosition(); sf::Vector2f FirstSize = First.GetSize(); sf::Vector2f FirstPosition2 = sf::Vector2f(FirstPosition1.x + FirstSize.x, FirstPosition1.y + FirstSize.y); sf::Vector2f SecondPosition1 = Second.GetPosition(); sf::Vector2f SecondSize = Second.GetSize(); sf::Vector2f SecondPosition2 = sf::Vector2f(SecondPosition1.x + SecondSize.x, SecondPosition1.y + SecondSize.y); if (FirstPosition1.x > SecondPosition2.x) return 2; if (FirstPosition2.x < SecondPosition1.x) return 2; if (FirstPosition1.y > SecondPosition2.y) return 1; if (FirstPosition2.y < SecondPosition1.y) return 1; return 0; }
und hier jetzt die wichtigen teile des codes
// Load the sprite image from a file sf::Image ImageSpieler; if (!ImageSpieler.LoadFromFile("sprite.png")) return EXIT_FAILURE; sf::Image Imageumgebung; if (!Imageumgebung.LoadFromFile("umgebung.png")) return EXIT_FAILURE; // Create the sprite sf::Sprite Spieler(ImageSpieler); sf::Sprite SpielerGhost(ImageSpieler); sf::Sprite umgebung[50]; for(int i=1; i<3; i++){ umgebung[i].SetImage(Imageumgebung); umgebung[i].SetPosition(100.f+10*i, 100.f); } Spieler.SetPosition(50.f, 100.f); float laufen = 100; float velx; float vely; // Start game loop while (App.IsOpened()) { //Save Player Posission sf::Vector2f AltePlayerPossition = Spieler.GetPosition(); SpielerGhost = Spieler; // Get elapsed time float ElapsedTime = App.GetFrameTime(); if (App.GetInput().IsKeyDown(sf::Key::Left)) velx = -laufen; if (App.GetInput().IsKeyDown(sf::Key::Right)) velx = laufen; if (App.GetInput().IsKeyDown(sf::Key::Up)) vely = -laufen; if (App.GetInput().IsKeyDown(sf::Key::Down)) vely = laufen; //HIER SOLLTE JETZT DIE KOLLISION GETESTET WERDEN....... velx = 0; vely = 0; // Clear screen App.Clear(sf::Color(255, 255, 255)); App.Draw(Spieler); for(int i=1; i<20; i++){ App.Draw(umgebung[i]); } // Display window contents on screen App.Display();
-
leider bin ich noch nicht so recht bewandert in c++ deshalb köntest du das mit den "Jede seite der Box Instanzen zuweisen" etwas genauer erklären?
Naja, du legst zum Beispiel eine Klasse "Box" an, die 4 Seitenlängen speichert.
Was gibt diese Methode hier zurück?
First.GetSize();
-
First.GetSize();gibt die länge und die Breite als Vektor aus. in meinem fall wo ich ja immer 10*10 Große Blöcke habe also immer 10^^
-
Alles klar.
jetzt hab ich schon eine Funktion die testet ob der Spieler mit Umgebung[X] Kollidiert.
Zeig mal her.
-
Zerod schrieb:
das ist die Funktion mit der ich Kollisionen prüfe:
int IsCollided(const sf::Sprite& First, const sf::Sprite& Second) { sf::Vector2f FirstPosition1 = First.GetPosition(); sf::Vector2f FirstSize = First.GetSize(); sf::Vector2f FirstPosition2 = sf::Vector2f(FirstPosition1.x + FirstSize.x, FirstPosition1.y + FirstSize.y); sf::Vector2f SecondPosition1 = Second.GetPosition(); sf::Vector2f SecondSize = Second.GetSize(); sf::Vector2f SecondPosition2 = sf::Vector2f(SecondPosition1.x + SecondSize.x, SecondPosition1.y + SecondSize.y); if (FirstPosition1.x > SecondPosition2.x) return 2; if (FirstPosition2.x < SecondPosition1.x) return 2; if (FirstPosition1.y > SecondPosition2.y) return 1; if (FirstPosition2.y < SecondPosition1.y) return 1; return 0; }
Mit dieser Funktion kann ich das Prüfen
-
ok ich bin jetzt so weit das ich eine Art Prüfung habe aber dor komme ich zu diesem Problem: