Monday, October 28, 2019

actionscript 3 - As3 Flash How to check if a bitmapdata is completely set to transparent using an eraser?


I'm trying to make a window-cleaning game with flash as3 on the timeline. (Sounds boring I know, but I realy have some fun idea's with it)


So I have: A dirtywindow movieclip on the bottom layer and a clean window movieclip on layer 2(mc1) on the layer above.


To hide the top layer(the dirty window) I assign a mask to it.


// this creates a mask that hides the movieclip on top
var mask_mc:MovieClip = new MovieClip();
addChild(mask_mc)

//assign the mask to the movieclip it should 'cover'
mc1.mask = mask_mc;


With a brush(cursor) the player wipes of the dirt ( actualy setting the fill from the mask to transparent so the clean window appears)


//add event listeners for the 'brush'
brush_mc.addEventListener(MouseEvent.MOUSE_DOWN,brushDown);
brush_mc.addEventListener(MouseEvent.MOUSE_UP,brushUp);

//function to drag the brush over the mask
function brushDown(dragging:MouseEvent):void{
dragging.currentTarget.startDrag();
MovieClip(dragging.currentTarget).addEventListener(Event.ENTER_FRAME,erase) ;

mask_mc.graphics.moveTo(brush_mc.x,brush_mc.y);
}

//function to stop dragging the brush over the mask
function brushUp(dragging:MouseEvent):void{
dragging.currentTarget.stopDrag();
MovieClip(dragging.currentTarget).removeEventListener(Event.ENTER_FRAME,erase);
}

//fill the mask with transparant pixels so the movieclip turns visible

function erase(e:Event):void{
with(mask_mc.graphics){
beginFill(0x000000);
drawRect(brush_mc.x,brush_mc.y,brush_mc.width,brush_mc.height);
endFill();
}

}

I hope you can help me with the following problem: The game-aspect of this should be the points the player get's for cleaning/erasing all the dirt.



Can anyone tell me how I can check if all pixels are set to transparency? So how to check if all the dirt has been erased? And than for example trace ("window cleaned")




I tried the compare() function but didn't have much luck with it :(...



Answer



A naive approach would be to simply perform a brute-force check on all pixels. As soon as you hit a non-transparent pixel you can stop searching further. This won't work very well with large images and can result in quite extensive searches if the last non-transparent pixels are at the end of the search.


There are two better ways I can think of:




  1. Similar to a brute-force check, start in the top-left (0, 0) of the image and check every pixel to see if it's non-transparent. If you hit a non-transparent pixel, the image isn't clear yet. So store that position and in the next iteration, start from that pixel instead (because all previous pixels have been marked as transparent anyway, so there's no point in checking them again). Your image will be cleared as soon as your search-position reaches the last pixel in the image.





  2. Calculate the sum of total pixels (eg. image.width * image.height) and store that in a variable. With every drawing-operation you count the amount of pixels that were set to transparent and subtract this value from the total. As soon as your total hits zero, you cleared all pixels. To count the pixels that turned transparent in one drawing-operation, you sample the brush area (for example by using bitmap.getPixels()) and count all the non-transparent pixels before you do the drawing operation.




No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...