Question

I´m making a game that simulates an industry of pan, and one of the process is Painting.

What I want to do is to let the player paint the pan, but i don´t want it to be easy using FILL, i want that the player paint the pan with an brush and then the game detects if all the area was painted and let the player advance.

For the painting i intend to use that library: http://www.nocircleno.com/graffiti/

But i have no idea how to detect if all the area was painted. Can someone show me some way of doing that?

Was it helpful?

Solution

One of the ways would be - you make a shielding BitmapData that has transparency and is opaque in place which you need your player to paint. (Color it as needed, but make sure the color is fully opaque). Then gather histogram() then query alpha vector for 255th value, this will be the initial value for zero percent filled. These range from 0-255, so you can't use 100 or any other fixed value. Then, while the player is painting, you draw the brush over that BitmapData with blendMode parameter set to BlendMode.ERASE, this will net your BitmapData to gain transparency where the brush was drawn. After your player finishes drawing by any means (say, the paint is used up), you run another histogram() over the BitmapData, and query the 255th value of alpha channel vector. 0 means the bitmap is fully transparent (or at least, only a small amount of pixels is left opaque), thus you can count a zero as 100% fill, for anything greater use the proportion.

var bd:BitmapData=new BitmapData(w,h,true,0x0); // fully transparent initial bitmap
bd.draw(yourPaintBase); // a shape that designates area to be painted. Must be fully opaque
var bm:Bitmap=new Bitmap(bd);
// position it as needed, so the area which should be painted is aligned to wherever you need
addChild(bm);
addEventListener(Event.ENTER_FRAME,doPaint);
var baseValue:int=bd.histogram()[3][255]; // Vector #3 contains alpha, #255 contains 
// percentage of those pixels that have alpha of 255 = fully opaque
function doPaint(e:Event):void {
    if (!areWePainting) return;
    var sh:Shape=getBrush(); // shuold return an existing Shape object reference for performance
    sh.x=e.localX;
    sh.y=e.localY; // we are drawing where the mouse is
    bd.draw(sh,null,null,BlendMode.ERASE);
    decreasePaint(); // we have used some paint
    if (noMorePaint()) {
        e.target.removeEventListener(Event.ENTER_FRAME,doPaint);
        var endValue:int=Math.floor(100*(1-bd.histogram()[3][255]/baseValue));
        // aligning to percentage. This is the value you seek
        reportFilledPercentage(endValue);
    }
}

OTHER TIPS

You can iterate over the pixels on your BitmapData and use getPixel() to check if the color of all those pixels is not white. If a white one is found, the image is not fully painted.

Something like this:

function containsWhite(bitmapData:BitmapData):Boolean
{
    for(var c:int = 0; c < bitmapData.width; c++)
    {
        for(var r:int = 0; r < bitmapData.height; r++)
        {
            // Check if pixel is white.
            if(bitmapData.getPixel(c, r) >= 0xFFFFFF)
            {
                return true;
            }
        }
    }

    return false;
}

Your essentially dealing with a collision detection problem. From looking at their API you could try something like a for loop with getColorAtPoint and try to determine they have drawn at each pixel.

If all else fails look into collision between the objects the library generates using the .hitTestObject method of an object.

See this: http://sierakowski.eu/list-of-tips/39-collision-detection-methods-hittest-and-hittestobject-alternatives.html

And this to see how someone handles collision with pixels: http://www.emanueleferonato.com/2010/08/05/worms-like-destructible-terrain-in-flash-part-2/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top