2015-03-12 18 views
5

ho trovato questo codice di controllo collisione Perfect Pixel e lo ha utilizzato nel mio codice:Pixel collisione perfetta con Config.ALPHA_8

public boolean isCollisionDetected(Bitmap bitmap1, int x1, int y1, 
     Bitmap bitmap2, int x2, int y2) { 
    Rect bounds1 = new Rect(x1, y1, x1 + bitmap1.getWidth(), y1 
      + bitmap1.getHeight()); 
    Rect bounds2 = new Rect(x2, y2, x2 + bitmap2.getWidth(), y2 
      + bitmap2.getHeight()); 

    if (Rect.intersects(bounds1, bounds2)) { 
     Rect collisionBounds = getCollisionBounds(bounds1, bounds2); 
     for (int i = collisionBounds.left; i < collisionBounds.right; i++) { 
      for (int j = collisionBounds.top; j < collisionBounds.bottom; j++) { 
       int bitmap1Pixel = bitmap1.getPixel(i - x1, j - y1); 
       int bitmap2Pixel = bitmap2.getPixel(i - x2, j - y2); 
       if (isFilled(bitmap1Pixel) && isFilled(bitmap2Pixel)) { 
        return true; 
       } 
      } 
     } 
    } 
    return false; 
} 

private Rect getCollisionBounds(Rect rect1, Rect rect2) { 
    int left = (int) Math.max(rect1.left, rect2.left); 
    int top = (int) Math.max(rect1.top, rect2.top); 
    int right = (int) Math.min(rect1.right, rect2.right); 
    int bottom = (int) Math.min(rect1.bottom, rect2.bottom); 
    return new Rect(left, top, right, bottom); 
} 

private boolean isFilled(int pixel) { 
    return pixel != Color.TRANSPARENT; 
} 

E ha funzionato perfettamente, nessun problema cosa così mai. Questo fino a quando ho impostare le immagini in Config_Alpha_8 utilizzando questo codice (a causa di problemi di RAM):

private Bitmap convert(Bitmap bitmap, Bitmap.Config config) { 
    Bitmap convertedBitmap = 
        Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), config); 
    Canvas canvas = new Canvas(convertedBitmap); 
    Paint paint = new Paint(); 
    paint.setColor(Color.BLACK); 
    canvas.drawBitmap(bitmap, 0, 0, paint); 
    return convertedBitmap; 
} 

Perché non succederà nulla, lo fa andare dentro isCollisioDetected, ho controllato con i registri! ma non rileva la collisione .. qualcuno può fornire una funzione di lavoro per il controllo della collisione perfetta dei pixel della bitmap con config_alpha_8?

risposta

3

Chiamare getPixel() su una bitmap con configurazione ALPHA_8 restituirà sempre zero. Questo sembra essere a bug

È possibile aggirare questo problema memorizzando i pixel di ciascuna bitmap come un array di byte:

byte[] pixelData = getPixels(convert(bitmap, Bitmap.Config.ALPHA_8)); 

... 

public byte[] getPixels(Bitmap bmp) { 
    int bytes = bmp.getRowBytes() * bmp.getHeight(); 
    ByteBuffer buffer = ByteBuffer.allocate(bytes); 
    bmp.copyPixelsToBuffer(buffer); 
    return buffer.array(); 
} 

Sarà necessario modificare la funzione di rilevamento delle collisioni un po ':

public boolean isCollisionDetected(byte[] pixels1, Bitmap bitmap1, int x1, int y1, 
      byte[] pixels2, Bitmap bitmap2, int x2, int y2) { 

     int width1 =bitmap1.getWidth(); 
     int height1=bitmap1.getHeight(); 
     int width2 =bitmap2.getWidth(); 
     int height2=bitmap2.getHeight(); 

     Rect bounds1 = new Rect(x1, y1, x1 + width1, y1 + height1); 
     Rect bounds2 = new Rect(x2, y2, x2 + width2, y2 + height2); 

     if (Rect.intersects(bounds1, bounds2)) { 
      Rect collisionBounds = getCollisionBounds(bounds1, bounds2); 
      for (int i = collisionBounds.left; i < collisionBounds.right; i++) { 
       for (int j = collisionBounds.top; j < collisionBounds.bottom; j++) { 
        byte bitmap1Pixel = pixels1[((j - y1) * width1) + (i - x1)]; 
        byte bitmap2Pixel = pixels2[((j - y2) * width2) + (i - x2)]; 
        if (isFilled(bitmap1Pixel) && isFilled(bitmap2Pixel)) { 
         return true; 
        } 
       } 
      } 
     } 
     return false; 
    } 

(... è possibile modificare i parametri bitmap nella rispettiva larghezza e altezza di tali bitmap e chiamare recycle().)

+0

Questo codice non influisce sulla bitmap per qualche motivo, non fa nulla, non lo colora di nero, e se lo uso e utilizzo anche il convertito non c'è ancora alcuna collisione. E sì io applico a nuovi bitmap caricato \t \t this.coin = BitmapFactory.decodeResource (getResources(), \t \t \t \t R.drawable.item_coin, opzioni); – SpoocyCrep

+0

quando converto bitmap in alpha_8 diventano neri, quando ho usato questo codice non è cambiato nulla in bitmap, significa che hanno ancora la stessa quantità di RAM di prima, no? – SpoocyCrep

+0

Dovrebbero usare meno. (1 byte per pixel). Potremmo provare a risolvere questo per chat: http://chat.stackoverflow.com/rooms/73375/android-pixel-perfect-collision –

0

Android Config_Alpha_8 non salva le informazioni sul colore, quindi quando si disegna la bitmap, l'aggiunta della vernice non farà nulla e tutti i controlli isFilled restituiranno false.

Neat pezzo di codice però.

+0

Capisco il problema, ma deve esserci una soluzione. I pixel vengono visualizzati sullo schermo, quindi è necessario un modo per ottenere la loro posizione, e da lì dovrebbe essere possibile un controllo di collisione. – SpoocyCrep