Fonction de collisions entre un tableau et des coordonées flottantes
Bonsoir à tous,
Tout d'abord, je dois avouer que mon titre est quelque peu obscur. :D
Dans le cadre d'un projet de Bomberman, je cherche à vérifier les collisions entre le joueur et les éléments fixes de la carte. Ces éléments sont stockés dans un tableau d'entiers à deux dimensions, et occupent chacun une case.
En revanche, les coordonnées de mon joueur qui se balade sont flottantes. Je dois donc faire interagir ici entiers et flottants.
Pour cela, je considère mon joueur comme une hitbox et je vérifie si chaque coin rentre dans une case. Pour plus de clarté, voici mon code :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
/*
bool checkCollisions(int x, int y, int offsetTable)
Check collisions between an entity and the map
offsetTable contain all offset (UP, DOWN, left, right)
Return true if there is a collision, false either
*/
bool CMap::checkCollisions(float x, float y, float offsetTable[]) {
// Init var for table
int tableX = 0;
int tableY = 0;
// Init pos vars
float posX = 0.f;
float posY = 0.f;
// UP left => x + offset left, y + offset UP
posX = x + offsetTable[LEFT];
posY = y + offsetTable[UP];
// Table UP left
tableX = (int)floor(posX);
tableY = (int)floor(posY);
// Check
if (posX >= (float)tableX && posX <= (float)(tableX + 1) && posY >= (float)tableY && posY <= (float)(tableY + 1) && m_mapTable[tableY][tableX] != FREE) {
cerr << "****************************************" << endl;
cerr << "Collision top left" << endl;
cerr << "posX : " << posX << " posY : " << posY << endl;
cerr << "tableX : " << tableX << " tableY " << tableY << endl;
cerr << "tableX + 1 : " << tableX + 1 << " tableY + 1 : " << tableY + 1 << endl;
cerr << "****************************************" << endl;
return true;
}
// UP right
posX = x + 1.f - offsetTable[RIGHT];
posY = y + offsetTable[UP];
// Table UP right
tableX = (int)floor(posX);
tableY = (int)floor(posY);
// Check
if (posX >= (float)tableX && posX <= (float)(tableX + 1) && posY >= (float)tableY && posY <= (float)(tableY + 1) && m_mapTable[tableY][tableX] != FREE) {
cerr << "****************************************" << endl;
cerr << "Collision top right" << endl;
cerr << "posX : " << posX << " posY : " << posY << endl;
cerr << "tableX : " << tableX << " tableY " << tableY << endl;
cerr << "tableX + 1 : " << tableX + 1 << " tableY + 1 : " << tableY + 1 << endl;
cerr << "****************************************" << endl;
return true;
}
// DOWN left
posX = x + offsetTable[LEFT];
posY = y + 1.f - offsetTable[DOWN];
// Table bottom left
tableX = (int)floor(posX);
tableY = (int)floor(posY);
// Check
if (posX >= (float)tableX && posX <= (float)(tableX + 1) && posY >= (float)tableY && posY <= (float)(tableY + 1) && m_mapTable[tableY][tableX] != FREE) {
cerr << "****************************************" << endl;
cerr << "Collision bottom left" << endl;
cerr << "posX : " << posX << " posY : " << posY << endl;
cerr << "tableX : " << tableX << " tableY " << tableY << endl;
cerr << "tableX + 1 : " << tableX + 1 << " tableY + 1 : " << tableY + 1 << endl;
cerr << "****************************************" << endl;
return true;
}
// DOWN right
posX = x + 1.f - offsetTable[RIGHT];
posY = y + 1.f - offsetTable[DOWN];
// Table bottom right
tableX = (int)floor(posX);
tableY = (int)floor(posY);
// Check
if (posX >= (float)tableX && posX <= (float)(tableX + 1) && posY >= (float)tableY && posY <= (float)(tableY + 1) && m_mapTable[tableY][tableX] != FREE) {
cerr << "****************************************" << endl;
cerr << "Collision bottom right" << endl;
cerr << "posX : " << posX << " posY : " << posY << endl;
cerr << "tableX : " << tableX << " tableY " << tableY << endl;
cerr << "tableX + 1 : " << tableX + 1 << " tableY + 1 : " << tableY + 1 << endl;
cerr << "****************************************" << endl;
return true;
}
return false;
} |
Les messages d'erreurs envoyées à la console sont là pour le débug.
Ma fonction fonctionne presque, mais il a y un problème ( et il est de taille ) : parfois mon bomberman se coince juste après une collision et je ne peux le faire ressortir car chaque vérification suivante se heurte à la collision. Seulement, ça devrait être impossible de se coincer étant donné que ma fonction devrait retourner false lors de la vérification (donc à t-1, avant le mouvement) et le mouvement ne devrait pas se faire...
Voyez-vous des incohérences dans mon code ?.
Merci d'avance
EDIT : Bouarf, honte à moi ; lors de mon déplacement effectif dans ma classe joueur, je rajoutais un facteur de vitesse... Qui n'était pas pris en compte pour la vérification des collisions ! Résolu ;)