Search code examples
actionscript-3bitmapdatahittest

AS3 - Check if BitmapData is completely obscured by other BitmapData


I'm looking to check if a BitmapData object is completely obscured by a BitmapData object. Is there something like the hitTest function but that makes sure every pixel is covered instead of any pixel?

Edit: It is important that transparent pixels are not included when checking if the object is obscured.


Solution

  • It's actually a pretty simple solution after all! Basically what you do is just capture the pixel values of the overlapping bitmap in the rectangle area that the overlapped bitmap occupies. You then iterate over that vector of values and as long as you don't have a 0 (completely transparent pixel), then you've completely covered the bitmap underneath.

    Here are the two bitmaps I used in this test:

    Overlapping bitmap:
    enter image description here

    Overlapped bitmap:
    enter image description here
    Code:

    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.utils.ByteArray;
    import flash.geom.Rectangle;
    
    var coveredBitmapData:BitmapData = new CoveredBitmapData();
    var coveringBitmapData:BitmapData = new CoveringBitmapData();
    
    
    var coveringBitmap:Bitmap = new Bitmap(coveringBitmapData, "auto", true);
    var coveredBitmap:Bitmap = new Bitmap(coveredBitmapData, "auto", true);
    
    coveredBitmap.x = Math.random() * (stage.stageWidth - coveredBitmap.width);
    coveredBitmap.y = Math.random() * (stage.stageHeight - coveredBitmap.height);
    
    stage.addChild(coveredBitmap);
    stage.addChild(coveringBitmap);
    
    stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMovement);
    
    function onMouseMovement(e:MouseEvent):void
    {
        coveringBitmap.x = mouseX - (coveringBitmap.width * .5);
        coveringBitmap.y = mouseY - (coveringBitmap.height * .5);
    
        checkIfCovering(coveringBitmap, coveredBitmap);
    }
    
    function checkIfCovering(bitmapA:Bitmap, bitmapB:Bitmap):Boolean
    {
        //bitmapA is the covering bitmap, bitmapB is the bitmap being overlapped
    
        var overlappedBitmapOrigin:Point = new Point(bitmapB.x, bitmapB.y);
    
        var localOverlappedBitmapOrigin:Point = bitmapA.globalToLocal(overlappedBitmapOrigin);
    
        var overlappingPixels:Vector.<uint> = bitmapA.bitmapData.getVector(new Rectangle(localOverlappedBitmapOrigin.x, localOverlappedBitmapOrigin.y, bitmapB.width, bitmapB.height));
    
        if(overlappingPixels.length == 0) {
            //This means that there is no bitmap data in the rectangle we tried to capture. So we are not at all covering the underlying bitmap.
            return false;
        }
    
        var i:uint = 0;
        for(i; i < overlappingPixels.length; ++i) {
            if(overlappingPixels[i] == 0) {
                return false;
            }
        }
    
        return true;
    }