flash - 使用 draw 方法时如何旋转 BitmapData。宽度高度边界裁剪/裁剪问题

标签 flash actionscript-3 actionscript

我编写了一个使用 BitmapData.hitTest 运行的碰撞检测类。基本上,每次更新时,都会调用 .draw 方法,然后对两个 BitmapData 进行 hitTest 以查看是否存在碰撞。

它工作得很好,但是如果我开始旋转我用于 BitmapData 的源 MovieClip,转换不会在绘制方法中注册。所以我所做的是在 draw 方法中传递一个 Matrix。这样可行。但这是实际问题。如果我将 BitmapData 输出到舞台上的位图,我会看到位图,事实上,它正在旋转,但现在它超出了 BitmapData 的边界(宽度和高度)。正在裁剪/剪裁源 MovieClip 的图像。

我的第一个猜测是旋转 BitmapData,但旋转似乎不可能。没有任何属性可以帮助您实现这一目标。还有别的办法吗?

更新:基本上,当 MovieClip 的位图克隆旋转到正坐标空间之外时,它不会被绘制。它在 BitmapData 设置的宽度和高度范围之外旋转。我可以将边界乘以 2,然后将位图置于设置边界内的中心,但原点永远不会固定,对象总是四处移动。效果很好,但无法将对象与任何特定点对齐。

这是我的独立测试代码。它要求您在舞台上有一个名为“iTest”的 MovieClip。我使用了一个相当垂直的箭头形状(高于它的宽度),这样我就可以在视觉上跟踪旋转并帮助强调剪裁问题:

var rotateTimer:Timer = new Timer(10);

function rotateObject_init():void
{
 rotateTimer.addEventListener(TimerEvent.TIMER, rotateObject);
 rotateTimer.start();
}

function rotateObject_stop():void
{
 rotateTimer.removeEventListener(TimerEvent.TIMER, rotateObject);
 rotateTimer.stop();
}

function rotateObject(_event:TimerEvent):void
{
 // Deletes the previous bitmap
 if (this.getChildByName("iTestClone") != null)
 {
  removeChild(this.getChildByName("iTestClone"));

  testClone = null;
  testData = null;
 }

 iTest.rotation += 1;

 // Capture source BitmapData
 var testData:BitmapData = new BitmapData(iTest.width, iTest.height, false, 0xFFFFFF); 

 // Capture source transformations
 var testMatrix:Matrix = new Matrix();
 testMatrix.scale(iTest.scaleX, iTest.scaleY);
 testMatrix.rotate( iTest.rotation * (Math.PI / 180) );
 testMatrix.translate(0, 0);

 // Draw source with matrix
 testData.draw(iTest, testMatrix);

 // Output Bitmap
 var testClone:Bitmap = new Bitmap(testData);
 testClone.name = "iTestClone";
 testClone.transform = testMatrix.tra
 addChild(testClone);

 // Always makes sure source is visible
 this.swapChildren(iTest, testClone);
}

rotateObject_init();

最佳答案

好问题!

我试图制作一个旋转 10 度的正方形的 BitmapData 克隆。为了获得位图数据的旋转,我使用了克隆对象的矩阵。正如您提到的,问题是由于旋转枢轴而导致的偏移量。

这是我的样子:

bounds

为了解决这个问题,我虽然如果我得到 BitmapData 和最右边点之间的差异,那将给我 x 的偏移量,并对 y 执行类似的操作,将使我在正确的位置地方。

几乎,我看起来好多了(只有一两个像素似乎受到伤害):

bounds 2

好的,我觉得我明白了:)

offset

那个偏移量是针对 x 的,但他误导的是,它是由边界矩形的 height 定义的,而不是 width .试试这个:

var box:Sprite = new Sprite();
box.graphics.lineStyle(0.1);
box.graphics.drawRect(0,0,150,100);
box.rotation = 10;
//get the size of the object rotated
var bounds:Rectangle = box.getBounds(this);
//make a bitmap data
var extra:int = 2;//cheating the trimmed pixels :)
var bitmapData:BitmapData = new BitmapData(bounds.width+extra,bounds.height+extra,false, 0x00009900);
//get the bottom left point
var bl:Point = getBottomLeft(box,bitmapData);
//get the matrix
var m:Matrix = box.transform.matrix;
//offset if
m.tx += Math.abs(bl.x);
//draw, using the offset, rotated matrix
bitmapData.draw(box,m);

var bitmap:Bitmap = new Bitmap(bitmapData);
bitmap.x = bitmap.y = 100;
addChild(bitmap);

function getBottomLeft(displayObject:DisplayObject,data:BitmapData):Point{
    var radius:int = displayObject.getBounds(displayObject).height;
    var angle:Number = displayObject.rotation * Math.PI / 180;
    var angle90:Number = angle + Math.PI * .5;
    return new Point(Math.cos(angle90) * radius, Math.sin(angle90) * radius);
}

您不需要在 BitmapData 构造函数中使用绿色背景,那是为了调试。 此外,您只需要左下角的 x 位置,因此您需要返回一个数字而不是一个点。

所以稍微短一点的版本是:

var box:Sprite = new Sprite();
box.graphics.lineStyle(0.1);
box.graphics.drawRect(0,0,150,100);
box.rotation = 10;

var bounds:Rectangle = box.getBounds(this);
var extra:int = 2;//cheating the trimmed pixels :)
var bitmapData:BitmapData = new BitmapData(bounds.width+extra,bounds.height+extra,false, 0x00009900);

var m:Matrix = box.transform.matrix;
m.tx += Math.abs(getLeftmost(box,bitmapData));
bitmapData.draw(box,m);

var bitmap:Bitmap = new Bitmap(bitmapData);
bitmap.x = bitmap.y = 100;
addChild(bitmap);

function getLeftmost(displayObject:DisplayObject,data:BitmapData):Number{
    var radius:int = displayObject.getBounds(displayObject).height;
    var angle90:Number = displayObject.rotation * Math.PI / 180 + Math.PI * .5;
    return Math.cos(angle90) * radius;
}

结果:

offset 2

HTH,乔治

self 提醒:小心你想要的东西^_^

关于flash - 使用 draw 方法时如何旋转 BitmapData。宽度高度边界裁剪/裁剪问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2165074/

相关文章:

html - Flash 文件上的下拉菜单

javascript - super 简单的音频播放器吗?

flash - 播放mp3流几个小时后Adobe Flash崩溃

Flash AS3 : How to prevent MouseEvent. MOUSE_OUT 当您将鼠标悬停在子 Sprite 上时

actionscript-3 - 在 Flex 3 的 TileList 中移动效果

java - 在 Android AIR 应用程序中设置 BroadcastReceiver

android - 使用 createJS 到 HTML5 以使其在 Android 设备上运行的 Flash 站点覆盖问题

actionscript-3 - 为什么属性在接口(interface)中不可声明

actionscript-3 - PNG 是否像 JPG 一样包含 EXIF 数据?

Java:找出对象的内存大小?