BitmapData.draw() Matrix problem
I've run into an issue where the BitmapData.draw() method isn't accurately subtracting image data from a .png that uses transparency.
I've put together a test file that shows this behavior, it's located here: http://www.filedropper.com/shield_1
In a nutshell, a sprite drops from the top of the screen and when it intersects with a sprite at the bottom of the screen, the sprite that was dropping takes out a chunk of the sprite at the bottom. I've got all of this working except that when i reset the x and y position of the sprite after its intersected the bottom sprite and it intersects with the bot开发者_如何学Ctom sprite again, it doesn't take the same size chunk out of the sprite at the bottom.
I apologize if I'm not explaining this well enough. If you a moment to look at the file I posted it will make sense.
Here's the code which requires two png files within the library with Linkage values of ShieldBase and SnowBall.
package
{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.geom.Point;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.events.Event;
public class Shield extends Sprite
{
public var baseBmpData:BitmapData = new ShieldBase(0,0);
public var baseBmp:Bitmap = new Bitmap(baseBmpData);
public var missileBitmapData:BitmapData = new SnowBall(0,0);
public var missileBitmap:Bitmap = new Bitmap(missileBitmapData);
public var missileMatrix:Matrix = new Matrix();
public function Shield()
{
baseBmp.y = 300;
baseBmp.x = 40;
stage.addChild(baseBmp);
missileBitmap.x = 85;
missileBitmap.y = 0;
stage.addChild(missileBitmap);
stage.addEventListener(Event.ENTER_FRAME, dropFromSky);
}
public function dropFromSky(e:Event)
{
for (var i:int=0; i<10; i++)
{
if (baseBmpData.hitTest(new Point(baseBmp.x,baseBmp.y),0x00,new Point(missileBitmap.x,missileBitmap.y)))
{
missileBitmap.y++;
missileMatrix = new Matrix();
missileMatrix.translate(baseBmp.x,baseBmp.y);
missileMatrix.tx = (missileBitmap.x - baseBmp.x);
missileMatrix.ty = (missileBitmap.y - baseBmp.y);
// public function draw(source:IBitmapDrawable, matrix:Matrix = null, colorTransform:flash.geom:ColorTransform = null, blendMode:String = null, clipRect:Rectangle = null, smoothing:Boolean = false):void
baseBmpData.draw(missileBitmap, missileMatrix, null, BlendMode.ERASE, null, true);
missileBitmap.x = rand(60, 140);
missileBitmap.y = 0;
}
else
{
missileBitmap.y++;
}
}
}
public function rand(low:Number=0, high:Number=1):Number
{
return Math.floor(Math.random() * (1+high-low)) + low;
}
}
}
I think the issue is with either the hitTest and/or BitmapData.draw() not working as expected.
many thanks,
devin
There are two problems.
1) The position that you test for the collision; if you use the center of the ball instead of the top-left then it works properly.
2) The drop shadow on your shield :
What happens is that the pixels on the edge of the shadow that are barely visible are causing
the hitTest
to succeed; I would suggest you remove the drop shadow from the image and apply it using an actual drop-shadow filter in flash.
To get it to work with the drop shadow I changed the alpha threshold in the hitTest
to 128
so that the semi-transparent pixels of the drop shadow are ignored.
You could leave the threshold at 0 but it looks odd at the beginning when the ball seemingly hits nothing.
Change this:
baseBmpData.hitTest(new Point(baseBmp.x,baseBmp.y),0x00,new Point(missileBitmap.x,missileBitmap.y))
to this:
baseBmpData.hitTest(new Point(baseBmp.x,baseBmp.y),128,new Point(missileBitmap.x+missileBitmap.width*0.5,missileBitmap.y+missileBitmap.height*0.5))
精彩评论