Springen mit Collision Detection?

BrknDevee

Mitglied
Nächstes Problem :)

Ich hab endlich nach langer Zeit Collision Detection implementieren können, bin aber bei der Implementierung des Springens auf ein Problem gestoßen,
und zwar muss ich herausfinden, ob der Spieler den Boden berührt oder nicht. Man kann ja einfach eine Variable in der Kollisionsmethode setzen,
aber damit kann ich nur herausfinden, ob der Spieler mit den Blöcken kollidiert und nicht,
ob der Spieler mit den Blöcken unter sich kollidiert, das heißt man kann sich an Wänden hochglitchen.

2. Versuch:
Man nimmt die Höhe des Spielers vor der Tastaturabfrage und dannach, rechnet die Differenz aus und wenn diese 0 ist, müsste er auf dem Boden stehen. Aber an dem Punkt, wo sich "kinetische und potentielle Energie ausgleichen", ist die Differenz auch 0, das heißt der Spieler würde weiterspringen.

Ich dachte eigentlich, das sei einfach genug, dass ich es lösen könnte, aber auch hier muss ich wieder um Rat fragen :/
Sorry für meine Unwissenheit und danke im Vorraus an jede Antwort :)

Hier der Link zu GitHub:
https://github.com/BrknDevee/iBl_project
 

JuKu

Top Contributor
Die Angaben sind leider nicht präzise genug.

Dem Github Link zufolge handelt es sich um ein 2D Plattformer Game?
Da weißt du doch anhand deiner Map, ob er den Boden berührt? Oder irre ich mich?
 

BrknDevee

Mitglied
Stimmt, das ist eine Idee :)
Tut mir Leid, das ist mein erstes Mal Collision Detection,
ich habs jetzt nicht so elegant gelöst, aber es klappt:

Ich nehme die Farbe des Pixels der Map an der Position direkt unter des Spielers und danneben und das System oben beschrieben mit der Differenz von y vorher und nachher zusammen, falls das grammatikalisch Sinn ergibt :D
 

Schmetterhand

Aktives Mitglied
Deine Lösung funktioniert vielleicht, ist aber nicht sehr schön. Deshalb, um die Seite herauszufinden, von welcher der Spieler mit einem Hindernis kollidiert, mußt Du dir einfach nur den Bewegungs-"Vektor" des Spielers bei der Kollision anschauen.
Pseudocode:
Code:
if (spieler.vX < 0) // Kollidiert links am Block.
if (spieler.vX > 0) // Kollidiert rechts am Block.
if (spieler.vY < 0) // Kollidiert unten am Block.
if (spieler.vY > 0) // Kollidiert oben am Block: Variable setzen, daß der Spieler springen darf!
(Vorausgesetzt, der Koordinatenursprung ist oben links)

Gruß,
Schmetterhand
 

BrknDevee

Mitglied
Oh, stimmt. Das scheint offensichtlich, ein Freund von mir hat gerade beim Testen das Problem wieder entdeckt, also werde ich mich dem Ganzen wohl nocheinmal annehmen müssen, nur ich benutze OpenGL, das heißt der Koordinatenursprung ist in der Mitte. Außerdem hab ich keinen Bewegungsvektor, wenn man den nicht einfach durch Subtrahieren der Position jetzt von der vorher bekommt.
 

JuKu

Top Contributor
Und außerdem, wie kann ein Vektor größer als 0 sein oder meinst du alle dessen Komponenten?

Diese Frage verwirrt mich ernsthaft. Wieso sollte ein Vektor nicht größer als 0 sein können? Er kann jeden beliebigen Wert annehmen.

Bezüglich Koordinatenursprung in der Mitte:
Dann baust du dir eben eine Kamera und verschiebst diesen meinetwegen nach links unten. Aber einen Unterschied macht es nicht.

Im einfachsten Fall hast du ein 2D Array in dieser Form:
Java:
boolean collidingObjects[][] = new boolean[width][height];

Wobei width die Anzahl der Tiles nach rechts und height die Anzahl der Tiles nach oben / unten sind. Irgendwie musst du ja deine Map aufbauen. Wenn ein true drin steht, kann der Spieler dieses Feld betreten, ansonsten nicht (dann ist dort ein Block oder was anderes).
Deine aktuelles Feld bekommst du so (wenn dein Koordinatenursprung unten links ist):
Java:
//width and height of tiles
int tileWidth = 32;
int tileHeight = 32;

//get current player position in tiles
int tileX = xInPixels / tileWidth;
int tileY = yInPixels / tileHeight;

Damit weißt du schon mal, an welcher Position der Spieler gerade steht.
Jetzt kannst du prüfen, ob das Tile unter dem Spieler mit dem Spieler kollidiert, oder nicht:
Java:
if (collidingObjects[tileX][tileY - 1] == true) {
    //play can pass tile
} else {
    //player cannot pass tile --> stop falling
}

Umgekehrt kannst du so prüfen, ob der Spieler springen kann:
Java:
if (collidingObjects[tileX][tileY + 1] == true) {
    //play can jump
} else {
    //player cannot jump
}

Das ist die einfachste Methode und so in etwa wurde es früher bei Super Mario (2D Plattformer) implementiert.

EDIT:
Wieso fängst du mit OpenGL an, wenn du nicht sooo viel Erfahrung damit besitzt?
Fang lieber kleiner an, z.B. mit libGDX!
 

InfectedBytes

Top Contributor
Diese Frage verwirrt mich ernsthaft. Wieso sollte ein Vektor nicht größer als 0 sein können? Er kann jeden beliebigen Wert annehmen.
Ein Vektor ist aber kein geordneter Körper. Ist der Vector (1,-1) größer, kleiner oder gleich 0?
Antwort: Nichts davon
Ich schätze mal @BrknDevee wollte mit seiner Frage darauf hinaus was denn bitte > 0 sein soll, denn der Vektor als ganzes kann so nicht verglichen werden. Man könnte aber eben über die einzelkomponenten oder die Länge argumentieren (wobei es mit der Länge recht witzlos ist, da diese immer >= 0 ist)



Ansonsten kann (und sollte) man boolean Abfragen wie folgt kürzen:
Java:
if(xyz == true) { ... } // Unnötig
if(xyz) { ... } // Besser/Schöner



Wieso fängst du mit OpenGL an, wenn du nicht sooo viel Erfahrung damit besitzt?
Fang lieber kleiner an, z.B. mit libGDX!

Dem kann ich nur zustimmen, für den Anfang ist OpenGL nicht gerade zu empfehlen. LibGDX nutzt selbst auch OpenGL, kümmert sich aber selbst schon um vieles, sodass man viel einfacher an sein Ziel kommt.
 

BrknDevee

Mitglied
Vielen Dank für die ganzen Antworten :)

Wieso fängst du mit OpenGL an
Nunja, ich hab vor einer Weile durch die Videos von ThinMatrix OpenGL kennengelernt, was sich dann ziemlich alternativlos in mein Hirn eingebrannt hat.

Ein Vektor ist aber kein geordneter Körper. Ist der Vector (1,-1) größer, kleiner oder gleich 0
Ja, das hab ich gemeint

Und da ich die Map aus einem PNG mache, kann ich ja gleich noch in ein Boolean[] schreiben, das ergibt schon Sinn, mit der Position des Spielers auf den Tiles muss ich noch einmal schauen, aber ihr habt mir extrem weiter geholfen, danke :))
 

BrknDevee

Mitglied
Vielen Dank an die ganzen Antworten!
Ich hab mich erstmal um andere Sachen gekümmert, aber jetzt muss ich mich diesem wohl auch widmen :/

Ich habe mir jetzt eine HashMap gemacht aus einem Vector2f und einem Boolean, um zu schauen, ob an dieser 2D Position ein Tile ist oder nicht.

2 Probleme:
1. Ich konnte die HashMap nur für ganze Zahlen definieren, aber wie würde das mit allen reellen gehen?
2. Ich habe für die Entity Position eine andere Position als für die Tiles, deshalb kann ich die nicht einfach so vergleichen, also müsste man sie umrechnen. Aber wie?

https://github.com/BrknDevee/iBl_project
 

JuKu

Top Contributor
Ansonsten kann (und sollte) man boolean Abfragen wie folgt kürzen:
Java:
if(xyz == true) { ... } // Unnötig
if(xyz) { ... } // Besser/Schöner

Recht hast du!
Ich habe es auch nur der Verständlichkeit wegen ausgesprochen, da ich nicht einschätzen kann, wie viel Erfahrung BrknDevee mitbringt.

Ich habe mir jetzt eine HashMap gemacht aus einem Vector2f und einem Boolean, um zu schauen, ob an dieser 2D Position ein Tile ist oder nicht.

Nimm lieber ein Array statt eine HashMap! Eine HashMap ist wesentlich langsamer als ein Array. Zumal du ein Array mit primitiven Datentypen haben kannst, eine HashMap aber komplexe Datentypen (Instanzen) benötigt --> GC Pressure.
Also statt:
Java:
Map<Vector2f,Boolean> map = new HashMap<>();

Dann das:
Java:
boolean tiles[][] = new boolean[width][height];

Oder was war deine Intention dahinter, eine HashMap zu nutzen?

Außerdem wichtig:
Eine HashMap nutzt die Methode hashCode() von Vector2f, um das ganze einzuordnen. Ich weiß nicht, wie die genaue Java Implementierung da aussieht, aber es ist möglich, dass der HashCode gleich bleibt, auch wenn du nachträglich die Koordinaten vom Vektor änderst.

1. Ich konnte die HashMap nur für ganze Zahlen definieren, aber wie würde das mit allen reellen gehen?

Wenn du wirklich HashMap verwenden willst, dann einfach statt Integer Float verwenden. Ein Vector2f kann doch auch float speichern, oder?

2. Ich habe für die Entity Position eine andere Position als für die Tiles, deshalb kann ich die nicht einfach so vergleichen, also müsste man sie umrechnen.

Wieso ist diese Position denn anders?
Bzw. was genau ist anders?
 

BrknDevee

Mitglied
Eine HashMap ist wesentlich langsamer als ein Array.
Ja, stimmt, ich glaube ich hab das nur zur Übersichtlichkeit gemacht, aber das ist ein Argument.

Wenn du wirklich HashMap verwenden willst, dann einfach statt Integer Float verwenden. Ein Vector2f kann doch auch float speichern, oder?
Das 'f' in Vector2f steht ja für float, ich hätte hierbei auch einen Vector2i nehmen können, nur ich dachte gestern -warum auch immer- das sei mit floats genauer, aber es geht ja um ganze Tiles.

Bzw. was genau ist anders
Bei einer 128 x 256 Tiles großen Welt sieht es so aus als müsste man zu der x und y Position 3 addieren und dann durch 2 dividieren, aber das ist anders wenn die Map größer oder kleiner wird.
 

mrBrown

Super-Moderator
Mitarbeiter
Nimm lieber ein Array statt eine HashMap! Eine HashMap ist wesentlich langsamer als ein Array. Zumal du ein Array mit primitiven Datentypen haben kannst, eine HashMap aber komplexe Datentypen (Instanzen) benötigt --> GC Pressure.
Die zusätzliche Belastung für den GC ist vermutlich so minimal, dass das nicht merkbar ist...

Eine HashMap nutzt die Methode hashCode() von Vector2f, um das ganze einzuordnen. Ich weiß nicht, wie die genaue Java Implementierung da aussieht, aber es ist möglich, dass der HashCode gleich bleibt, auch wenn du nachträglich die Koordinaten vom Vektor änderst.
Ich hoffe doch, ein Vektor ist immutable...

HashMaps kommen mit geänderten Hashes nicht klar, das Objekt bleibt immer unter seinem ursprünglichem Hash gespeichert und ist auch nur unter dem findbar
 

BrknDevee

Mitglied
Oh, ich hätte es früher ausprobieren müssen, sorry.
Aus irgendeinem Grund muss ich die Entity Position mit 5 addieren und dann durch 2 dividieren, um zur Tile Position zu kommen, egal bei welcher Größe der Map
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Zu bestimmte Stellen im code springen? Frameworks - Spring, Play, Blade, Vaadin & Co 8
Xentox501 Jump & Run: Beim springen bewegen(rechts,links) Frameworks - Spring, Play, Blade, Vaadin & Co 1
R Player springen lassen mit Gravity Frameworks - Spring, Play, Blade, Vaadin & Co 2
it_is_all Springen zw. JPanels mit setVisible() Frameworks - Spring, Play, Blade, Vaadin & Co 4
C Suche Tutorial für - Spielfiguren springen lassen Frameworks - Spring, Play, Blade, Vaadin & Co 4
A Springen an Seitenanfang verhindern Frameworks - Spring, Play, Blade, Vaadin & Co 5
G Springen mithilfe von Trigonometrie Frameworks - Spring, Play, Blade, Vaadin & Co 4
J Spieler springen lassen Frameworks - Spring, Play, Blade, Vaadin & Co 24
Paul15 Nach vorne springen Frameworks - Spring, Play, Blade, Vaadin & Co 4
A RadioButtons springen nicht automatisch auf false Frameworks - Spring, Play, Blade, Vaadin & Co 3
S Von A nach B springen Frameworks - Spring, Play, Blade, Vaadin & Co 7
D Zum Code springen Frameworks - Spring, Play, Blade, Vaadin & Co 5
T DesktopPane mit GridLayout ohne, dass Fenster springen Frameworks - Spring, Play, Blade, Vaadin & Co 14
K von Button zu Zelle in Tabelle- zu anderer Zelle springen Frameworks - Spring, Play, Blade, Vaadin & Co 2
F.S.WhiTeY JSF: h:dataTable / p:DataGrid : Pagination und alphabetisch springen Frameworks - Spring, Play, Blade, Vaadin & Co 2
T OpenGL ES: Zoom und pan springen immer wieder zur Ausgangsposition zurück Frameworks - Spring, Play, Blade, Vaadin & Co 4
? In GZIPInputStream "springen" Frameworks - Spring, Play, Blade, Vaadin & Co 1
L \n , in die nächste Zeile springen Frameworks - Spring, Play, Blade, Vaadin & Co 11
M Zum Anfang eines Programmes springen Frameworks - Spring, Play, Blade, Vaadin & Co 2
S ...aus while schleife springen Frameworks - Spring, Play, Blade, Vaadin & Co 3
C Vom Case zur Case-Auswahl springen? Frameworks - Spring, Play, Blade, Vaadin & Co 9
R Txt Datei mit Notepad öffnen und zu bestimmter Zeile springen Frameworks - Spring, Play, Blade, Vaadin & Co 12
F GUI Seiten springen + Timer mit Eingabe Frameworks - Spring, Play, Blade, Vaadin & Co 8
G Cursor Positionieren/mit Tabulator springen? Frameworks - Spring, Play, Blade, Vaadin & Co 8
F In NetBeans zum nächsten Fehler springen Frameworks - Spring, Play, Blade, Vaadin & Co 7
K Zu Fehler im Projekt springen Frameworks - Spring, Play, Blade, Vaadin & Co 2
K Per Tastaturbefehl zu nächstem Lesezeichen springen Frameworks - Spring, Play, Blade, Vaadin & Co 2
J Zur Auffälligkeit springen - Shortcut Frameworks - Spring, Play, Blade, Vaadin & Co 7
E JTable neue Zeile springen?! Frameworks - Spring, Play, Blade, Vaadin & Co 1
L Wenn Aufgaben erledigt sind, auf Programmanfang springen? Frameworks - Spring, Play, Blade, Vaadin & Co 12
J zu einer Zeile zürück springen Frameworks - Spring, Play, Blade, Vaadin & Co 9
R JEditorPane an bestimmte Stelle springen Frameworks - Spring, Play, Blade, Vaadin & Co 2
S Direkt zur Methode springen die in der Klasse und nicht im Interface implementiert? Frameworks - Spring, Play, Blade, Vaadin & Co 4

Ähnliche Java Themen

Neue Themen


Oben