Guckuck
Ich habe leider überhaupt nichts richtiges gefunden zu dem Thema.
In meinem 2d Jump'n'Run Spiel funktionieren die Grundfunktionen wunderbar, Kartenanzeige, einfache Physik, Kollisionen mit den Tiles, läuft wunderbar.
Nun wollte ich das alles etwas erweitern, und zwar wollte ich mehr Tiletypen haben. Also nicht nur Würfel, mit denen man kollidiert und nicht durch gehen kann. Sowas wie Stacheln, sodass der Spieler sterben soll, wenn man draufhüpft, oder auch Plattformen, durch die man zwar durchspringen kann, aber sobald man drauffällt von oben nicht durch kann. Der Problem liegt sicher an dem Aufteilung der Klassen.
Ich habe eine Klasse Tile, in der ich die BildID speichere und die eine abstrakte Funktion "collidesWith" hat. Da wird angegeben, in welche Richtung sich der Spieler gerade bewegt (dadurch wird der Spieler bei einem Block auch an die richtige Position gestellt), dann wird das der Spieler / das Projektil / was auch immer angegeben, und dann die Position des Tiles.
Davon werden alle anderen Tyletypen abgeleitet, wie zum Beispiel BlockTile, wo auch die Kollision stattfinden und der Spieler zurückgesetzt wird.
Durch die Funktion kann ich leider nur angeben, ob eine Kollision stattfand oder nicht. Wenn ich dann aber zum Beispiel einen Stachel-Block haben möchte, dann funktioniert das ja nicht mehr so gut, da meine Sprite-Klasse keine Variable für Leben hat und somit auch nciht sterben kann. Ich hab schon daran gedacht, dass man noch sowas wie eine Funktion "getTileType" einbaut, die die Art des Tiles zurückgibt und dann in entsprechenden Klassen (Player/Enemy...) darauf reagiert wird. Zusätzlich sollte der Spieler noch einen Schub anch oben bekommen, wenn er einen Stachel berührt, damit er die Chance hat, da weg zu kommen. Ich auch schon daran gedacht, in der Klasse "Collision", die dazu da ist, alle relevanten Tiles auf Kollisionen zu überprüfen, eine ArrayList <Tile> zurückzugeben, damit bekäme man alle Tiles, mit denen man kollidiert und kann so einmal durchlaufen und für jedes Tile entsprechend reagiere, wenn er nötig ist. Problem wäre dann, das ich, wenn ich zum Beispiel zwischen 2 Stacheln stehe, 2 mal Leben abgezogen bekomme, was ich ja nicht will.
Ich habe noch ein Bild angehängt, wie ich das mit den Kollisionen mache. Die grünen Kreuze beim roten Rechteck (Spieler) stellen Kollisionspunkte da, die in Tiles umgerechnet werden und so das Tile ermittelt wird, wo der Punkt sich befindet. Deswegen ist der Spieler auch 1 Pixel in den Boden "eingelassen". Da sieht man, dass er mit 2 stacheln kollidiert, aber er soll die Reaktion nur einmal machen, und nciht zweimal für beide Stacheln.
Ich hoffe das Problem ist einigermaßen verständlich... wäre sehr dankbar für einen Ansatz zur Lösung, ich stehe momentan sehr auf dem Schlauch
Ich habe leider überhaupt nichts richtiges gefunden zu dem Thema.
In meinem 2d Jump'n'Run Spiel funktionieren die Grundfunktionen wunderbar, Kartenanzeige, einfache Physik, Kollisionen mit den Tiles, läuft wunderbar.
Nun wollte ich das alles etwas erweitern, und zwar wollte ich mehr Tiletypen haben. Also nicht nur Würfel, mit denen man kollidiert und nicht durch gehen kann. Sowas wie Stacheln, sodass der Spieler sterben soll, wenn man draufhüpft, oder auch Plattformen, durch die man zwar durchspringen kann, aber sobald man drauffällt von oben nicht durch kann. Der Problem liegt sicher an dem Aufteilung der Klassen.
Ich habe eine Klasse Tile, in der ich die BildID speichere und die eine abstrakte Funktion "collidesWith" hat. Da wird angegeben, in welche Richtung sich der Spieler gerade bewegt (dadurch wird der Spieler bei einem Block auch an die richtige Position gestellt), dann wird das der Spieler / das Projektil / was auch immer angegeben, und dann die Position des Tiles.
Java:
public abstract class Tile {
protected int tileID;
public Tile(int tileID) {
this.tileID = tileID;
}
public int getTileID() {
return this.tileID;
}
public abstract boolean collidesWith(Direction direction, Sprite sprite, int x, int y);
}
Davon werden alle anderen Tyletypen abgeleitet, wie zum Beispiel BlockTile, wo auch die Kollision stattfinden und der Spieler zurückgesetzt wird.
Java:
public class Block extends Tile {
public Block(int tileID) {
super(tileID);
}
public boolean collidesWith(Direction direction, Sprite sprite,
int x, int y) {
if (direction == Direction.LEFT) {
Vector2f pos = sprite.getPosition();
sprite.setPosition(new Vector2f((x + 1) * 32, pos.y));
return true;
}
if (direction == Direction.RIGHT) {
float width = sprite.getShape().getWidth();
Vector2f pos = sprite.getPosition();
sprite.setPosition(new Vector2f(x * 32 - width, pos.y));
return true;
}
if (direction == Direction.BOTTOM) {
float height = sprite.getShape().getHeight();
Vector2f pos = sprite.getPosition();
sprite.setPosition(new Vector2f(pos.x, y * 32 - height + 1));
return true;
}
if (direction == Direction.TOP) {
Vector2f pos = sprite.getPosition();
sprite.setPosition(new Vector2f(pos.x, (y + 1) * 32));
return true;
}
return false;
}
}
Durch die Funktion kann ich leider nur angeben, ob eine Kollision stattfand oder nicht. Wenn ich dann aber zum Beispiel einen Stachel-Block haben möchte, dann funktioniert das ja nicht mehr so gut, da meine Sprite-Klasse keine Variable für Leben hat und somit auch nciht sterben kann. Ich hab schon daran gedacht, dass man noch sowas wie eine Funktion "getTileType" einbaut, die die Art des Tiles zurückgibt und dann in entsprechenden Klassen (Player/Enemy...) darauf reagiert wird. Zusätzlich sollte der Spieler noch einen Schub anch oben bekommen, wenn er einen Stachel berührt, damit er die Chance hat, da weg zu kommen. Ich auch schon daran gedacht, in der Klasse "Collision", die dazu da ist, alle relevanten Tiles auf Kollisionen zu überprüfen, eine ArrayList <Tile> zurückzugeben, damit bekäme man alle Tiles, mit denen man kollidiert und kann so einmal durchlaufen und für jedes Tile entsprechend reagiere, wenn er nötig ist. Problem wäre dann, das ich, wenn ich zum Beispiel zwischen 2 Stacheln stehe, 2 mal Leben abgezogen bekomme, was ich ja nicht will.
Ich habe noch ein Bild angehängt, wie ich das mit den Kollisionen mache. Die grünen Kreuze beim roten Rechteck (Spieler) stellen Kollisionspunkte da, die in Tiles umgerechnet werden und so das Tile ermittelt wird, wo der Punkt sich befindet. Deswegen ist der Spieler auch 1 Pixel in den Boden "eingelassen". Da sieht man, dass er mit 2 stacheln kollidiert, aber er soll die Reaktion nur einmal machen, und nciht zweimal für beide Stacheln.
Ich hoffe das Problem ist einigermaßen verständlich... wäre sehr dankbar für einen Ansatz zur Lösung, ich stehe momentan sehr auf dem Schlauch