2017-06-29 4 views
1

Ich arbeite gerade an einem Top-Down-Shooter und habe Probleme mit der Kollision. Meine Welt besteht aus Fliesen (64x64). Die Kacheln und die Objekte sind Rechtecke. Der Spieler bewegt sich mit einer Geschwindigkeit von beispielsweise 2,74 (und nicht in Pixeln für eine sanftere Bewegung). Aber wenn es um die Kollision zwischen dem Spieler (einer Entität) und einer Wand geht, habe ich einige Probleme. Um zu überprüfen, ob es eine Kollision gibt, nehme ich die aktuelle Position meines Spielers und seine Bewegungsgeschwindigkeit, um zu berechnen, wo seine nächste Position sein würde und ob es zu einer Kollision kommt. Aber ich überprüfe jeden Pixel auf dem Weg, damit ich kein Hindernis überspringen kann, auch wenn die Bewegungsgeschwindigkeit sehr hoch ist. Sagen wir einfach, die aktuelle Position des Spielers ist X: 200 Y: 200 und er bewegt 2,74 Pixel ein Häkchen in x-Richtung. Mein Spiel prüft nun, ob es eine Kollision bei X: 201 Y: 200, X: 202 Y: 200 oder X: 202.74 Y: 200 gibt und wenn nicht, bewegt sich der Spieler in diese Position. Wenn ich jetzt versuche, den Player weiter in x-Richtung zu bewegen, und es eine 0,26 Pixel entfernte Wand gibt, bewegt sich der Spieler nicht und hinterlässt eine winzige Lücke. Ich habe versucht, den Abstand zwischen Spieler und Mauer zu berechnen und diesen Betrag der Position des Spielers hinzuzufügen, aber dafür muss ich wissen, welche Seite der Mauer der Spieler trifft. Ich möchte auch, dass der Spieler sich auf und ab bewegen kann, wenn die Wand, die er trifft, vor ihm und umgekehrt ist.Java - Pixel-Perfect Collision - Lücke zwischen Spieler und Wand

Hier ist meine Kollisionsverfahren (in Java):

public static boolean collision(float ex, float ey, int width, int height) { // ex, ey would be the next position of the player 
    if (ex < 0 || ex + width > worldWidth || ey < 0 || ey + height > worldHeight) return true; // checks if this position is in the world 
    int firstTileX = (int) (ex/Tile.TILE_SIZE); // calculates tiles he could possible collide width 
    int firstTileY = (int) (ey/Tile.TILE_SIZE); 
    int lastTileX = (int) ((ex + width - 1)/Tile.TILE_SIZE); 
    int lastTileY = (int) ((ey + height - 1)/Tile.TILE_SIZE); 
    for (int y = firstTileY; y <= lastTileY; y++) { 
     if (y < 0) continue; // checks for out of bounds 
     if (y >= worldTileHeight) break; 
     for (int x = firstTileX; x <= lastTileX; x++) { 
      if (x < 0) continue; 
      if (x >= worldTileWidth) break; 
      if (tiles[y][x].solid) return true; // if the tile is solid -> collision found 
     } 
    } 
    return false; // no collision found 
} 

Und meine Bewegung Methode:

public void move(float xa, float ya) { 
    float nx, ny; 
    while (xa != 0 || ya != 0) { 
     nx = x; 
     ny = y; 
     if (xa != 0) { 
      if (Math.abs(xa) > 1) { // if the x-speed is greater than 1 
       nx = x + MathUtil.abs(xa); // returns -1 for negative numbers and 1 for positiv 
       xa -= MathUtil.abs(xa); 
      } else { // less than 1 
       nx = x + xa; 
       xa = 0; 
      } 
     } 
     if (ya != 0) { // same here 
      if (Math.abs(ya) > 1) { 
       ny = y + MathUtil.abs(ya); 
       ya -= MathUtil.abs(ya); 
      } else { 
       ny = y + ya; 
       ya = 0; 
      } 
     } 
     if (!Level.collision(nx, ny, width, height)) setPosition(nx, ny); // checks if there is an collision and sets the new position if not 
     else if (!Level.collision(nx, y, width, height)) x = nx; // if there was a collision check if the player can walk in x direction 
     else if (!Level.collision(x, ny, width, height)) y = ny; // or in y direction 
    } 
} 

Mein Problem der so ziemlich das gleiche wie CoderMusgrove das Problem in seinem Posten ist() :

Zusammenfassung & Frage

Ich habe ein Problem, wo, wenn die Geschwindigkeit einer Entity größer ist als die Entfernung von der Kachel, in die sie hineingeht, wird sie mindestens ein Pixel zwischen sich und der Kachel hinterlassen, und das mag ich wirklich nicht. Welchen Algorithmus könnte ich verwenden, um den kleinsten Unterschied zwischen der Entity und der Kachel zu finden?

Wenn Sie weitere Informationen benötigen, werde ich es gerne hinzufügen.

Danke für Ihre Hilfe!

+0

Überprüfen Sie diese Antwort https://Stackoverflow.com/a/43979300/5343269, es ist für Javascript, aber ich denke, Konzepte sind gleich. – 11thdimension

Antwort

0

Leicht auflösbar durch Änderung Ihrer Interpretation.

Sie behalten eine gebrochene Position für feinkörnige Geschwindigkeit bei. Ignoriere den Bruch zum Zwecke der Kollisionserkennung und -anzeige (wenn du ein Subpixel-Rendering durchführen würdest, führe die Kollision auf der Subpixel-Rendering-Genauigkeitsstufe durch).

int screenX = (int) Math.round(objX); 
int screenY = (int) Math.round(objY); 
// rendering and collision detection based on rounded position