pheopix
pheopix

Reputation: 41

AS3 : How do I clear graphics in a specific pixel/area

I know that you use graphics.clear to clear all the graphics but that clears the graphics from the stage, I would like to clear graphics in a specific pixel(s) or between x-y value how do I do that?

Upvotes: 4

Views: 1219

Answers (3)

Paweł Audionysos
Paweł Audionysos

Reputation: 606

Open stack overflow to answer some questions, think for next hour about how holes are placed in cheese... :)

You could also set blendMode property of your hole object to BlendMode.ERASE in combination with cacheAsBitmap. This works similar to masks except you would be actually drawing the wholes and not the area outside them. Here is an example:

//make cheese
var cheese:Sprite = new Sprite();
cheese.cacheAsBitmap = true;
stage.addChild(cheese);
cheese.x = cheese.y = 10;

//define holes 
var holes:Shape = new Shape();
holes.blendMode = BlendMode.ERASE;
cheese.addChild(holes);

//draw cheese
var g = cheese.graphics;
g.beginFill(0xFFCC00);
g.drawRect(0,0,200,150);

//**Attack chees with mices.
g = holes.graphics;
for (var i:int = 0; i < 10; i++){
    g.beginFill(0xFF00FF);
    var hx = Math.random()*(cheese.width-7)+7;
    var hy = Math.random()*(cheese.height-7)+7;
    var s = Math.random()*15;
    g.drawCircle(hx, hy, s);
    g.endFill();
}

Result would be something like that:

enter image description here

edit:

Turns out that you don't need to use cacheAsBitmap if you set blend mode of parent object to LAYER (doc says it should be set automatically...) So you can use cheese.blendMode = BlendMode.LAYER; instead of cheese.cacheAsBitmap = true;. And if I remember correctly, masks also don't require cahceAsBitmap, even with NORMAL blending mode.

Upvotes: 3

Aaron Beall
Aaron Beall

Reputation: 52133

The way to do this would be with a mask. Using an alpha mask (both mask and maskee use cacheAsBitmap=true) you can draw transparent pixels onto the mask to erase parts. The basic approach would be:

  1. Put all your graphics that you want to be effected by the mask in a common container (if you mean for everything to be cut, then they are already in a common container: the stage or root timeline.)

  2. Draw a bitmap data object that has a transparent "hole" in the area you want to erase. For example:

    // fill the stage with a solid rectangle
    var maskBitmapData:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xff000000);
    // erase part of it by drawing transparent pixels
    maskBitmapData.fillRect(new Rectangle(20, 20, 200, 100), 0);
    
    // create the mask object
    var maskBitmap:Bitmap = new Bitmap(maskBitmapData);
    maskBitmap.cacheAsBitmap = true; // this makes the mask an alpha mask
    addChild(maskBitmap);
    
  3. Set the container's .mask property. For example, to mask the entire main timeline:

    root.cacheAsBitmap = true; // this makes the mask an alpha mask
    root.mask = maskBitmap;
    

Upvotes: 5

Organis
Organis

Reputation: 7316

There's no way to do that with graphics. I just tried, drawing transparent shapes does not create holes, alas.

You should convert the graphics you have into Bitmap instance and work with pixels:

package
{
    import flash.geom.Matrix;
    import flash.geom.Rectangle;

    import flash.display.Sprite;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.DisplayObject;

    public class Holey extends Sprite
    {
        public function Holey() 
        {
            super();

            // Lets create some example graphics.
            graphics.beginFill(0x990000);
            graphics.drawCircle(200, 200, 100);
            graphics.endFill();

            // Convert into raster and make 1 pixel transparent.
            var aBit:Bitmap = rasterize(this);
            aBit.bitmapData.setPixel32(50, 50, 0x00000000);

            graphics.clear();
            addChild(aBit);
        }

        private function rasterize(source:DisplayObject):Bitmap
        {
            // Obtain bounds of the graphics.
            var aBounds:Rectangle = source.getBounds(source);

            // Create raster of appropriate size.
            var aRaster:BitmapData = new BitmapData(aBounds.width, aBounds.height, true, 0x00000000);

            // Make an offset to capture all the graphics.
            var aMatrix:Matrix = new Matrix;
            aMatrix.translate(-aBounds.left, -aBounds.top);

            aRaster.draw(source, aMatrix);
            return new Bitmap(aRaster);
        }
    }
}

Upvotes: 7

Related Questions