2013-01-07 3 views
1

J'ai implémenté un système de collision simple basé sur des tuiles dans mon jeu descendant, mais j'ai des problèmes pour me déplacer dans les virages. Actuellement, mes programmes prennent le point central du joueur et développent une tuile sur une grille carrée de 20px (le cbackground gris alternant). Il vérifie les tuiles haut, bas, gauche et droite pour les collisions, et s'il en trouve un, il passe à l'étape suivante.Collision à base de carreaux; Problèmes de collision de coin

L'étape suivante consiste à vérifier où se trouve le joueur dans la tuile. Pour cela, j'ai une fonction appelée getCenterDistanceFromCurrentTile() (nom de la création, je sais). Ceci renvoie un Vector2i (x et y) de la distance entre le point central de la tuile et le point central du joueur. Je l'utilise ensuite de la manière suivante.

  • S'il y a une tuile de mur à gauche, et x la distance du joueur < 0 (le joueur est à la gauche de la Centerpoint la tuile courante), le joueur est déplacé vers la x de la tuile à côté de la mur.
  • S'il y a un mur à droite et que la distance x du joueur est> 0 (à droite du point central de la tuile actuelle), le joueur est déplacé vers le x de la tuile à côté du mur.
  • Cela continue pour l'axe Y de la même manière.

Mon problème est avec la diagonale. Je ne vérifie pas les collisions diagonales actuellement, mais il semble que je devrai le faire. J'ai déjà fait une tentative pour l'implémenter, mais le joueur saute quand ils atteignent un coin. J'utilisais les méthodes ci-dessus du joueur x < 0 et joueur y < 0 ensemble, qui n'a pas fonctionné. J'ai fait quelques images pour mieux expliquer mon problème.

Problem image 1

Cette image montre mon système de collision fonctionne bien, avec une collision à gauche (indiquée par la tuile bleue), et les tuiles roses en cours de vérification, mais aucune collision trouvé. La tuile verte montre la tuile actuelle du joueur, et le carré rouge montre la position actuelle du joueur.

Problem image 2

Cette image montre clairement le problème que j'ai. Aucun des carreaux roses n'est entré en collision avec quoi que ce soit, donc les x et y du joueur n'ont pas besoin d'être vérifiés.

Comment devrais-je vérifier les collisions de coin dans mon jeu?

Mon code de vérification de collision actuel;

public boolean isWall(Vector2i loc) 
{ 
    return this.isWall(loc.x, loc.y); 
} 

public boolean isWall(int x, int y) 
{ 
    if (x < 0) return true; 
    if (y < 0) return true; 
    if (y > map[0].length-1) return true; 
    if (x > map.length-1) return true; 
    return map[x][y]; 
} 

public void phys(Player plr) { 
    Vector2i playerTile = plr.getTile(); 
    // Left 
    if (isWall(playerTile.x-1, playerTile.y)) 
    { 
     Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true); 
     if (distanceFromTile.x < 0) 
     { 
      plr.setX(playerTile.x*BLOCK_SIZE); 
     } 
    } 
    // Right 
    if (isWall(playerTile.x+1, playerTile.y)) 
    { 
     Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true); 
     if (distanceFromTile.x > 0) 
     { 
      plr.setX(playerTile.x*BLOCK_SIZE); 
     } 
    } 
    // Up 
    if (isWall(playerTile.x, playerTile.y-1)) 
    { 
     Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true); 
     if (distanceFromTile.y < 0) 
     { 
      plr.setY(playerTile.y*BLOCK_SIZE); 
     } 
    } 
    // Down 
    if (isWall(playerTile.x, playerTile.y+1)) 
    { 
     Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true); 
     if (distanceFromTile.y > 0) 
     { 
      plr.setY(playerTile.y*BLOCK_SIZE); 
     } 
    } 
} 

Répondre

1

Votre méthode physique peut renvoyer une valeur booléenne selon que le lecteur entre en collision avec l'un des murs. Vous pouvez ensuite utiliser le résultat de cette fonction pour décider si vous souhaitez revenir à l'emplacement précédent dans l'espace où vous étiez avant de vous déplacer ou, si vous n'avez pas été en collision, de continuer. Cela nécessiterait que vous vérifiiez tous les murs adjacents autour du lecteur. Cela introduirait une manière beaucoup plus propre d'itération à travers les vérifications de collision dans la méthode physique.

Une telle amélioration ressemblerait à ceci:

public boolean phys(Player plr) 
{ 
    java.awt.Rectangle playerBounds = new java.awt.Rectangle(plr.x, plr.y, BLOCK_SIZE, BLOCK_SIZE); 

    for (int y = 0; y < 3; y++) 
    { 
     for (int x = 0; x < 3; x++) 
     { 
      // Skip the tile the player is on assuming that he is not on a wall already 
      if (x == 1 && y == 1) continue; 

      java.awt.Rectangle bounds = new java.awt.Rectangle(/*tile at (x, y) xpos*/, /*tile at (x, y) ypos*/, BLOCK_SIZE, BLOCK_SIZE); 

      if (bounds.intersects(playerBounds)) 
      { 
       return true; 
      } 
     } 
    } 

    // Did not collide 
    return false; 
} 
+1

Merci, j'ai utilisé cela comme un pointeur et fixe. Mon code modifié; https://gist.github.com/4485362 –