为什么此功能不适用于不同的分辨率?
Why doesn't this function work on different resolution?
我正在寻找像素级碰撞检测,因为 hitTestObject
和 hitTestPoint
对于不规则形状不是很有效。
我发现了这个 link : Collision Detection of Sprites in Actionscript 3.0 Flash
link 包含检测不规则影片剪辑碰撞的功能,效果很好。它只有一个问题,它不适用于不同的分辨率。
例如,我想在全屏模式下工作,所以我输入了以下代码:
import flash.display.StageDisplayState;
stage.displayState = StageDisplayState.FULL_SCREEN ;
当.SWF文件全屏工作时,该功能不起作用。
当我在键盘上按"Esc"退出全屏时,功能正常
此外,如果我调整 .SWF 文件的 window 大小,该功能将再次失效!!
这是一个很棒的功能,易于使用,我真的需要它..但我不知道为什么会出现这种奇怪的行为!!
函数是:
trace("Collided: " + (areaOfCollision(mc1, mc2) != null));
trace("Where: " + areaOfCollision(mc1, mc2));
function areaOfCollision(object1:DisplayObject, object2:DisplayObject, tolerance:int = 255):Rectangle {
if (object1.hitTestObject(object2)) {
var limits1:Rectangle = object1.getBounds(object1.parent);
var limits2:Rectangle = object2.getBounds(object2.parent);
var limits:Rectangle = limits1.intersection(limits2);
limits.x = Math.floor(limits.x);
limits.y = Math.floor(limits.y);
limits.width = Math.ceil(limits.width);
limits.height = Math.ceil(limits.height);
if (limits.width < 1 || limits.height < 1) return null;
var image:BitmapData = new BitmapData(limits.width, limits.height, false);
var matrix:Matrix = object1.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
image.draw(object1, matrix, new ColorTransform(1, 1, 1, 1, 255, -255, -255, tolerance));
matrix = object2.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
image.draw(object2, matrix, new ColorTransform(1, 1, 1, 1, 255, 255, 255, tolerance), BlendMode.DIFFERENCE);
var intersection:Rectangle = image.getColorBoundsRect(0xFFFFFFFF, 0xFF00FFFF);
if (intersection.width == 0) return null;
intersection.offset(limits.left, limits.top);
return intersection;
}
return null;
}
更新: 我做了一个简单的试用项目来测试功能,但问题仍然存在。在项目中,您会发现两颗星。其中之一可以被拖动。当两颗星相互碰撞时,会出现一段文字。但是当我重新调整 window 的大小以使其变大时,文本根本没有出现!!
这是 link :
http://www.fileconvoy.com/dfl.php?id=g43d4a989bccefabb99964751142bbc6fb6af8d9e4
问题在于绘制碰撞所需的位图。
var matrix:Matrix = object1.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
以上代码仅适用于 stage.scaleMode
等于 StageScaleMode.NO_SCALE
因此我们需要计算正确的矩阵并将其提供给BitmapData
draw
方法。
所以这个
image.draw(object1, matrix, new ColorTransform(1, 1, 1, 1, 255, -255, -255, tolerance));
应该变成
image.draw(object1, getCorrectMatrix(object1, limits), new ColorTransform(1, 1, 1, 1, 255, -255, -255, tolerance));
function getCorrectMatrix(object:DisplayObject, hitRectangle:Rectangle):Matrix {
// get the concatenated matrix from the root (global stage)
var rootConcatenatedMatrix : Matrix = target.root.transform.concatenatedMatrix;
// convert the target's 0,0 position to global position
var localToGlobal:Point = object.localToGlobal( new Point() );
// get the concatenatedMatrix from the target
var matrix:Matrix = object.transform.concatenatedMatrix;
// translate the x,y coordinates,
matrix.tx = localToGlobal.x - hitRectangle.x;
matrix.ty = localToGlobal.y - hitRectangle.y;
// this is important!!
// the 'a' parameter of the matrix is the value that affects the x position when scaling or rotating.
// the 'd' parameter of the matrix is the value that affects the y position when scaling or rotating.
// We devide these values from our matrix and the rootConcatenated matrix to position our final matrix correctly.
matrix.a = matrix.a / rootConcatenatedMatrix.a;
//matrix.d = matrix.d / rootConcatenatedMatrix.d;
return matrix;
}
这可能有助于弄清楚碰撞函数发生了什么。
创建一个空位图并将其添加到舞台。
var collisionDrawingHelper:Bitmap = new Bitmap();
addChild(collisionDrawingHelper);
然后在 areaOfCollision
函数中,在图像变量绘制之后添加这个 collisionDrawingHelper.bitmapData = image
...
matrix = object2.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
image.draw(object2, matrix, new ColorTransform(1, 1, 1, 1, 255, 255, 255, tolerance), BlendMode.DIFFERENCE);
collisionDrawingHelper.bitmapData = image;
var intersection:Rectangle = image.getColorBoundsRect(0xFFFFFFFF, 0xFF00FFFF);
...
我正在寻找像素级碰撞检测,因为 hitTestObject
和 hitTestPoint
对于不规则形状不是很有效。
我发现了这个 link : Collision Detection of Sprites in Actionscript 3.0 Flash
link 包含检测不规则影片剪辑碰撞的功能,效果很好。它只有一个问题,它不适用于不同的分辨率。
例如,我想在全屏模式下工作,所以我输入了以下代码:
import flash.display.StageDisplayState;
stage.displayState = StageDisplayState.FULL_SCREEN ;
当.SWF文件全屏工作时,该功能不起作用。
当我在键盘上按"Esc"退出全屏时,功能正常
此外,如果我调整 .SWF 文件的 window 大小,该功能将再次失效!!
这是一个很棒的功能,易于使用,我真的需要它..但我不知道为什么会出现这种奇怪的行为!!
函数是:
trace("Collided: " + (areaOfCollision(mc1, mc2) != null));
trace("Where: " + areaOfCollision(mc1, mc2));
function areaOfCollision(object1:DisplayObject, object2:DisplayObject, tolerance:int = 255):Rectangle {
if (object1.hitTestObject(object2)) {
var limits1:Rectangle = object1.getBounds(object1.parent);
var limits2:Rectangle = object2.getBounds(object2.parent);
var limits:Rectangle = limits1.intersection(limits2);
limits.x = Math.floor(limits.x);
limits.y = Math.floor(limits.y);
limits.width = Math.ceil(limits.width);
limits.height = Math.ceil(limits.height);
if (limits.width < 1 || limits.height < 1) return null;
var image:BitmapData = new BitmapData(limits.width, limits.height, false);
var matrix:Matrix = object1.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
image.draw(object1, matrix, new ColorTransform(1, 1, 1, 1, 255, -255, -255, tolerance));
matrix = object2.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
image.draw(object2, matrix, new ColorTransform(1, 1, 1, 1, 255, 255, 255, tolerance), BlendMode.DIFFERENCE);
var intersection:Rectangle = image.getColorBoundsRect(0xFFFFFFFF, 0xFF00FFFF);
if (intersection.width == 0) return null;
intersection.offset(limits.left, limits.top);
return intersection;
}
return null;
}
更新: 我做了一个简单的试用项目来测试功能,但问题仍然存在。在项目中,您会发现两颗星。其中之一可以被拖动。当两颗星相互碰撞时,会出现一段文字。但是当我重新调整 window 的大小以使其变大时,文本根本没有出现!! 这是 link :
http://www.fileconvoy.com/dfl.php?id=g43d4a989bccefabb99964751142bbc6fb6af8d9e4
问题在于绘制碰撞所需的位图。
var matrix:Matrix = object1.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
以上代码仅适用于 stage.scaleMode
等于 StageScaleMode.NO_SCALE
因此我们需要计算正确的矩阵并将其提供给BitmapData
draw
方法。
所以这个
image.draw(object1, matrix, new ColorTransform(1, 1, 1, 1, 255, -255, -255, tolerance));
应该变成
image.draw(object1, getCorrectMatrix(object1, limits), new ColorTransform(1, 1, 1, 1, 255, -255, -255, tolerance));
function getCorrectMatrix(object:DisplayObject, hitRectangle:Rectangle):Matrix {
// get the concatenated matrix from the root (global stage)
var rootConcatenatedMatrix : Matrix = target.root.transform.concatenatedMatrix;
// convert the target's 0,0 position to global position
var localToGlobal:Point = object.localToGlobal( new Point() );
// get the concatenatedMatrix from the target
var matrix:Matrix = object.transform.concatenatedMatrix;
// translate the x,y coordinates,
matrix.tx = localToGlobal.x - hitRectangle.x;
matrix.ty = localToGlobal.y - hitRectangle.y;
// this is important!!
// the 'a' parameter of the matrix is the value that affects the x position when scaling or rotating.
// the 'd' parameter of the matrix is the value that affects the y position when scaling or rotating.
// We devide these values from our matrix and the rootConcatenated matrix to position our final matrix correctly.
matrix.a = matrix.a / rootConcatenatedMatrix.a;
//matrix.d = matrix.d / rootConcatenatedMatrix.d;
return matrix;
}
这可能有助于弄清楚碰撞函数发生了什么。
创建一个空位图并将其添加到舞台。
var collisionDrawingHelper:Bitmap = new Bitmap();
addChild(collisionDrawingHelper);
然后在 areaOfCollision
函数中,在图像变量绘制之后添加这个 collisionDrawingHelper.bitmapData = image
...
matrix = object2.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);
image.draw(object2, matrix, new ColorTransform(1, 1, 1, 1, 255, 255, 255, tolerance), BlendMode.DIFFERENCE);
collisionDrawingHelper.bitmapData = image;
var intersection:Rectangle = image.getColorBoundsRect(0xFFFFFFFF, 0xFF00FFFF);
...