我编写了一个使用BitmapData.hitTest工作的碰撞检测类。基本上,每次更新时,调用.draw方法,然后两个BitmapData相互命中,以查看是否存在冲突。
它工作得很好,但是如果我开始旋转我用于BitmapData的源MovieClip,则转换不会在draw方法中注册。所以我所做的是在draw方法中通过Matrix。这样可行。但这是实际问题。如果我将BitmapData输出到舞台上的Bitmap,我看到Bitmap 实际上是旋转,但现在它超出了BitmapData的边界(宽度和高度)。这是裁剪/剪裁源MovieClip的图像。
我的第一个猜测是旋转BitmapData,但似乎不可能旋转。没有任何属性可以帮助你解决这个问题。还有另一种方式吗?
UPDATE :基本上,当MovieClip的Bitmap克隆旋转到正坐标空间之外时,它不会被绘制。它在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();
答案 0 :(得分:4)
好问题!
我试图将一个正方形的BitmapData克隆旋转10度。为了获得位图数据的旋转,我使用了克隆对象的矩阵。正如您所提到的,问题是由于旋转枢轴而产生的偏移。
以下是我的看法:
为了解决这个问题,我认为如果我得到了BitmapData和最右边点之间的区别,那将给出x的偏移量,并为y做类似的操作,会让我在右边地点。
几乎,我看起来更好(只有一两个像素似乎受到伤害):
好的,我觉得我得到了:)
该偏移是针对 x ,但他误导的是,它是由边界矩形的高度定义的,而不是宽度 。试试这个:
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;
}
结果:
HTH,乔治
自我注意:小心你想要的^ _ ^
答案 1 :(得分:0)
您说bitmapData的边界导致裁剪,但您将边界设置为对象的宽度和高度。这表明返回的宽度和高度实际上是不正确的(即没有考虑旋转)。
也许尝试使用getBounds()来查找iTest的实际宽度和高度:
// Capture source BitmapData
var bounds:Rectangle = iTest.getBounds(iTest);
var testData:BitmapData = new BitmapData(bounds.width, bounds.height, false, 0xFFFFFF);
我不完全确定这是否会起作用 - 我还没有测试过这些: - )
答案 2 :(得分:0)
只需使用rotation属性:
THENAMEOFMovieClip.rotation=number;
数字是您想要旋转的度数。