Je ne connais pas Android, donc je ne sais pas quels outils vous avez à votre disposition, mais je peux vous dire un moyen de mettre en œuvre cela en termes généraux. La facilité de ce processus dépend de ce qu'Android vous propose. Vous allez avoir besoin de matrices ou au moins elles simplifieront beaucoup les calculs.
Pour commencer, effectuez un contrôle de collision de la boîte englobante et revenez immédiatement s'ils ne se heurtent pas afin d'éviter d'autres calculs. C'est logique car si les boîtes englobantes ne se heurtent pas, il est garanti qu'aucun pixel ne se heurtera non plus.
Ensuite, si un contrôle de collision parfait de pixels est nécessaire, le point le plus important est que vous devez effectuer ce contrôle dans le même espace . Cela peut être fait en prenant chaque pixel de l'image-objet A, en appliquant une série de transformations afin de les placer dans l'espace local de l'image-objet B, puis en vérifiant s'il entre en collision avec un pixel quelconque à cette position sur l'image-objet B. Une collision se produit lorsque les deux pixels vérifié sont opaques.
Donc, la première chose dont vous avez besoin est de construire une matrice mondiale pour chacun des sprites. Il existe probablement des didacticiels en ligne qui vous apprennent à en créer un, mais il devrait s'agir essentiellement d'une concaténation de quelques matrices plus simples dans l'ordre suivant:
Translation(-Origin) * Scale * Rotation * Translation(Position)
L'utilité de cette matrice est qu'en multipliant un point dans l'espace local - et par exemple si vous obtenez les pixels en utilisant une méthode comme celle-ci, bitmap.getPixelAt(10,20)
10,20 est défini dans l'espace local - par la matrice mondiale correspondante le déplacera dans l'espace mondial:
LocalA * WorldMatrixA -> World
LocalB * WorldMatrixB -> World
Et si vous inversez les matrices, vous pouvez également aller dans la direction opposée, c'est-à-dire transformer des points de l'espace mondial en chacun des espaces locaux du sprite en fonction de la matrice que vous avez utilisée:
World * InverseWorldMatrixA -> LocalA
World * InverseWorldMatrixB -> LocalB
Donc, pour déplacer un point de l'espace local du sprite A vers l'espace local du sprite B , vous devez d'abord le transformer en utilisant la matrice mondiale du sprite A, afin de le placer dans l'espace mondial, puis en utilisant la matrice du monde inverse du sprite B , pour l'intégrer dans l'espace local de sprite B:
LocalA * WorldMatrixA -> World * InverseWorldMatrixB -> LocalB
Après la transformation, vous vérifiez si le nouveau point tombe dans les limites de l'image-objet B, et si c'est le cas, vous vérifiez le pixel à cet endroit comme vous l'avez fait pour l'image-objet A. Ainsi, le processus entier devient quelque chose comme ça (en pseudocode et non testé) :
bool PixelCollision(Sprite a, Sprite B)
{
// Go over each pixel in A
for(i=0; i<a.Width; ++i)
{
for(j=0; j<a.Height; ++j)
{
// Check if pixel is solid in sprite A
bool solidA = a.getPixelAt(i,j).Alpha > 0;
// Calculate where that pixel lies within sprite B's bounds
Vector3 positionB = new Vector3(i,j,0) * a.WorldMatrix * b.InverseWorldMatrix;
// If it's outside bounds skip to the next pixel
if(positionB.X<0 || positionB.Y<0 ||
positionB.X>=b.Width || positionB.Y>=b.Height) continue;
// Check if pixel is solid in sprite B
bool solidB = b.getPixelAt(positionB.X, positionB.Y).Alpha > 0;
// If both are solid then report collision
if(solidA && solidB) return true;
}
}
return false;
}