Saturday, March 19, 2011

Not all effort results in progress

I got it in my head today to make a useful variation of FlxSprite. Basically, I just want to add some simple masking, a function that will let you mask of portions of the sprite as transparent.

The actual pixels of a sprite are stored in a BitmapData object called _pixels. So my bright idea was to store all the masking info into another BitmapData object called _alphamask, and combine the mask with original image to get the masked out image. A little research, and it looks like BitmapData.copyChannel() should let me transfer the alpha channel data from _alphamask to _pixels without touching anything else on the image.



package com.chipacabra.Jumper
{
// Don't use this, it doesn't work yet

 import flash.display.BitmapData;
 import flash.display.BitmapDataChannel;
 import flash.display.BlendMode;
 import flash.geom.Point;
 import flash.geom.Rectangle;
 import org.flixel.FlxG;
 import org.flixel.FlxSprite;

 public class MaskedSprite extends FlxSprite
 {
  private var _alphamask:BitmapData;
  private var _unmasked:BitmapData; //Store the unmasked data so we can restore it
  
  public function MaskedSprite(X:Number = 0, Y:Number = 0, SimpleGraphic:Class = null)
  {
   super(X, Y, SimpleGraphic);
   _alphamask = FlxG.createBitmap(_pixels.width, _pixels.height, 0x00000000);  //Initialize the alpha mask so it's sized right
   _unmasked = _pixels; // Probably not necessary, but better safe than sorry
  }
  
  override public function loadGraphic(Graphic:Class, Animated:Boolean = false, Reverse:Boolean = false, Width:uint = 0, Height:uint = 0, Unique:Boolean = false):FlxSprite
  {
   _alphamask = FlxG.createBitmap(_pixels.width, _pixels.height, 0x00000000);
   var temp:FlxSprite = super.loadGraphic(Graphic, Animated, Reverse, Width, Height, Unique);
   _unmasked = _pixels;
   return temp;
  }
  
  public function addRectangleMask(X:int, Y:int, Width:int, Height:int):void
  {
   var rect:Rectangle = new Rectangle(X, Y, Width, Height);
   _alphamask.fillRect(rect, 0xFFFFFFFF); // Add the rectangle to the masked region
   _pixels.copyChannel(_alphamask, new Rectangle(0, 0, _alphamask.width, _alphamask.height), new Point(0, 0), BitmapDataChannel.ALPHA, BitmapDataChannel.ALPHA); // This SHOULD copy the alpha channel of the mask to the image, but it's not working
  }
  
  public function clearMask():void
  {
   _alphamask.floodFill(0, 0, 0x00000000);
   _pixels = _unmasked;
  }
 }
}

As mentioned in the code comments, this isn't working, and I'm not entirely sure why. As much as this is bugging me, I don't actually need this code at all. For the purposes I have in mind, I could just as easily brute-force it, and just make a spritesheet with the transparencies already incorporated into each frame. Still, I'll probably come back to this sooner or later, but for now I'm just going to leave this here to remind myself where I left off, and to show a little more of how I'm putting off working on the next element of Jumper.

Incidentally, I'm planning on doing some basic item code next (keys and doors), followed by level transitions.

No comments:

Post a Comment