Collision Detection bei Tile Map

skappler

Aktives Mitglied
Hallo Leute
Ich arbeite momentan an einem 2D Shooter und brauche Hilfe bei der Kollision zwischen dem Spieler und der Map.
Ich habe meine Map als 2 dimensionales Array aus Tiles gespeichert, wobei jedes Tiles eine boolean Variable hat, ob man über das Tile laufen darf oder nicht.
Meine Tiles sind 32x32 Pixel und mein Player 32x64.
Ich arbeite nun schon mehrere Tage daran aber komme zu keinem funktionierenden Ergebnis.

Hat einer einen guten Ansatz für mich?

Gruß,
skappler
 

TimoH.

Mitglied
überprüfe doch bevor du deinen Spieler bewegst, ob die Tile zu der du laufen würdest begehbar ist, wenn ja, bewege den Spieler und wenn nicht dann halt nicht :)
 

skappler

Aktives Mitglied
Ja aber ich komme mit den Koordinaten nicht wirklich klar. Dazu kommt, dass mein Player doppelt so hoch wie ein Tile ist und sich flüßig bewegen lässt (also nicht immer genau auf einem Tile liegt, sondern auf mehreren).
 

TimoH.

Mitglied
Du kannst die Spielerkoordinate doch in die dazugehörige Tile umrechnen.

x = Spieler.x / Tile.Width
y = Spieler.y / Tile.Height
 

skappler

Aktives Mitglied
Ja schon klar. Aber wie gestalte ich dann die abfrage, ohne dass sie sich überschneiden? Zum Beispiel wenn ich nach links will oder nach oben will muss ich ja das linke obere Eck checken. Wenn ich dann zum Beispiel an der Linken Wand stehe kann ich mich nichtmehr nach oben bewegen.
 

TimoH.

Mitglied
Warum denn, du guckst doch immer nur wo der neue Ankunftspunkt ist, wenn der halt nicht betretbar ist, dann kannst du da halt nicht hin.

Schritte:
- Berechne neue Position
- Wenn Tile an neuer Position betretbar, dann bewege dich, ansonsten nicht

Du musst natürlich in die berechnung eventuell die Größe deines Spieler mit reinnehmen, jenachdem, wie du die Bewegung generell implementiert hast.
 

Fu3L

Top Contributor
Bewegst du dich nach oben, prüfst du halt
x = Spieler.x / Tile.Width
y = (Spieler.y+Spieler.height) / Tile.Height

nach unten halt:

x = Spieler.x / Tile.Width
y = Spieler.y / Tile.Height

Links und rechts (und auch diagonal) ähnlich.
 

Degush

Aktives Mitglied
Du überprüfst, ob sich im nächsten Frame, in der neue Positionen für den Spieler vorliegen, ein undurchsichtiger Punkt der Spielergrafik und ein undurchsichtiger Punkt eines Tiles, das nicht begehbar ist, überlappen.
Dazu solltest du erst orüfen, ob sich die bounding boxes schneiden
 

skappler

Aktives Mitglied
Du überprüfst, ob sich im nächsten Frame, in der neue Positionen für den Spieler vorliegen, ein undurchsichtiger Punkt der Spielergrafik und ein undurchsichtiger Punkt eines Tiles, das nicht begehbar ist, überlappen.
Dazu solltest du erst orüfen, ob sich die bounding boxes schneiden

Mein Player und auch meine Tiles haben eine getBounds() Methode. Aber wie überprüf ich den nächsten Frame?
 

mavinatic

Bekanntes Mitglied
Es ist doch recht simpel, ich bin momentan etwa an der gleichen Stelle wie du. Ich habe das folgender Maßen aufgebaut:

Ich errechne mir die Tile-Position aus und hole mir das Tile aus meinem Tile-Array und überprüfe ob man auf dem Tile sich bewegen darf oder nicht. Jedoch ist dieser Code-Snippet nicht ganz ausgereift, aber auf alle Fälle mal ein Anfang.
Java:
	@Override
	public void move()
	{	
//		System.out.println("movementData:");
//		System.out.println(this.getPositionX()+"|"+this.getPositionY());
//		System.out.println(this.getMapX()+"|"+this.getMapY());
		if(handler.isKeyForward() && isMovableOnTile('n') && !handler.isKeyMenu())	
			this.setPositionY(this.getPositionY() - this.getEntityMovementSpeed());
		
		if(handler.isKeyBackward() && isMovableOnTile('s') && !handler.isKeyMenu())
			this.setPositionY(this.getPositionY() + this.getEntityMovementSpeed());
		
		if(handler.isKeyLeft() && isMovableOnTile('w') && !handler.isKeyMenu())
			this.setPositionX(this.getPositionX() - this.getEntityMovementSpeed());
		
		if(handler.isKeyRight() && isMovableOnTile('e') && !handler.isKeyMenu())
			this.setPositionX(this.getPositionX() + this.getEntityMovementSpeed());	
	}
	
	/*
	 * CollisionDetectionViaPx
	 */
	public boolean isMovableOnTile(char dir)
	{
		float x = 0;
		float y = 0;
		
		if(dir=='n')
		{
			x = getMapX()/Tile.SIZE;
			y = (getMapY()-this.getEntityMovementSpeed())/Tile.SIZE;
			Tile currentTile = this.getCurrentLevel().getTile((int)x,(int)y);
			return currentTile.isMovable();
		}
		if(dir=='s')
		{
			x = getMapX()/Tile.SIZE;
			y = (getMapY()+this.getEntityMovementSpeed())/Tile.SIZE;
			Tile currentTile = this.getCurrentLevel().getTile((int)x,(int)y);
			return currentTile.isMovable();	
		}
		if(dir=='w')
		{
			x = (getMapX()-this.getEntityMovementSpeed())/Tile.SIZE;
			y = getMapY()/Tile.SIZE;
			Tile currentTile = this.getCurrentLevel().getTile((int)x,(int)y);
			return currentTile.isMovable();
		}
		if(dir=='e')
		{
			x = (getMapX()+this.getEntityMovementSpeed())/Tile.SIZE;
			y = getMapY()/Tile.SIZE;
			Tile currentTile = this.getCurrentLevel().getTile((int)x,(int)y);
			return currentTile.isMovable();	
		}
		return false;
	}
 

skappler

Aktives Mitglied
Ich habe jetzt versucht zu prüfen ob sich die Bounds überschneiden, wenn die Koordinaten erhöht sind.

Mein Code lautet:
Java:
public boolean checkCollision(int dir){
		// up 0, right 1, down 2, left 3
		

		int xx =(int) player.x - offsetx;
		int yy = (int) player.y - offsety;
		
		Rectangle r;
		
		switch(dir){
		case 0: r = new Rectangle(xx, yy-2, 32, 66);
			break;
		case 1: r = new Rectangle(xx, yy, 34, 64);
			break;
		case 2: r = new Rectangle(xx, yy, 32, 66);
			break;
		case 3: r = new Rectangle(xx-2,yy,34,64);
			break;
		default: r = new Rectangle();
		}
		
		for(int x = 0; x< world.width;x++){
			for(int y = 0; y < world.height;y++){
				
					if(world.world[x][y].getBounds().intersects(r) && world.world[x][x].isSolid()){
						return true;
					}
				
			}
		}
				
		return false;
}

Ich laufe hier durch die gesamte Map (sehr uneffizient ich weiß, aber auf die schnelle zum testen am einfachsten) und teste ob sich der Player überschneidet und ob das Tile Solid ist, also nicht begehbar.
Allerdings wird aus irgendeinem Grund immer false zurück gegeben.

Was mache ich falsch?
 

Fu3L

Top Contributor
Java:
if(world.world[x][y].getBounds().intersects(r) && world.world[x][x].isSolid()){

Eigentextblindheit.. Das Problem, wenn man zu lange dran arbeitet^^ world[x][x] wird evtl. der Übeltäter sein. Wenn nicht alleine, dann nochmal melden^^
 

Fu3L

Top Contributor
Zeig mal getBounds() und die Methoden, wo das Rectangle initialisiert wird. Außerdem die isSolid() Abfrage.

Das mit den xOffset und yOffset könnte es natürlich auch sein, aber das andere scheint mir gefühlt wahrhscheinlicher.

Außerdem bau mal ein System.out.println(dir); ein. Am besten auch System.out.println(xx + ":" + yy);
 

skappler

Aktives Mitglied
Hat sich gerade erledigt :D
Ich bin so doof :p Im Konstruktor der Tile Klasse hat this.width = width und this.height = height gefehlt, weshalb die getBounds() Methode immer ein Rectangle mit width und height 0 geliefert hat.
Ich muss mehr auf meine Konstruktoren achten. Das ist schon der dritte Bug der durch fehlende initialisierungen verursacht wurde.

Naja vielen Dank dann mal, ohne deine Frage hät ich das nie gefunden :p
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Collision Detection in einem 2D Sandbox Game. Spiele- und Multimedia-Programmierung 2
W Collision Detection/Prevention bei Drag & Drop Spiele- und Multimedia-Programmierung 23
M pixel perfect collision detection bei rotierenden Bildern Spiele- und Multimedia-Programmierung 13
T PacMan - Collision Spiele- und Multimedia-Programmierung 2
D Physik Engine und Collision Spiele- und Multimedia-Programmierung 5
TheSorm Collision an einer bestimmten Seite eine Rectangles abfragen Spiele- und Multimedia-Programmierung 3
Bananabert Collision Grid Spiele- und Multimedia-Programmierung 10
T LWJGL 3D Objekt Collision: Wie? Spiele- und Multimedia-Programmierung 11
E Bounding Box Collision/intersection aber wie? Spiele- und Multimedia-Programmierung 10
T Collision mit Bildern Spiele- und Multimedia-Programmierung 3
D Collision Spiele- und Multimedia-Programmierung 3
D collision mit images und pixelgrabber Spiele- und Multimedia-Programmierung 12
J Harris Corner Detection Spiele- und Multimedia-Programmierung 3
T "Dirty Rectangle Detection" bei BufferedImages? Spiele- und Multimedia-Programmierung 8
D Isometric Tile Map Beispiel gesucht Spiele- und Multimedia-Programmierung 1
J Lichtupdate in tile-basiertem Spiel Spiele- und Multimedia-Programmierung 4
J Tile-basierte, zufällige Levelgenerierung Spiele- und Multimedia-Programmierung 2
F quaxlis tile map programming tutorial prob Spiele- und Multimedia-Programmierung 4
S Kollision tile-based 2D Plattformer Spiele- und Multimedia-Programmierung 2
Kenan89 Theoretische Frage zu Tile Spielkarten Spiele- und Multimedia-Programmierung 9
L Tile Map als Array? Spiele- und Multimedia-Programmierung 23
V Tile Wars Spiele- und Multimedia-Programmierung 57
I Timebased tile scrolling wirkt unsauber. Spiele- und Multimedia-Programmierung 7
J Isometric Tile Game (x,y) inklusive Z cordinaten? Spiele- und Multimedia-Programmierung 2

Ähnliche Java Themen

Neue Themen


Oben