【问题标题】:Why doesn't this function work on different resolution?为什么此功能不适用于不同的分辨率?
【发布时间】:2015-04-09 04:56:34
【问题描述】:

我正在寻找像素级碰撞检测,因为 hitTestObjecthitTestPoint 对于不规则形状不是很有效。

我发现了这个链接:Collision Detection of Sprites in Actionscript 3.0 Flash

该链接包含一个检测不规则影片剪辑碰撞的功能,并且效果很好。它只有一个问题,它不适用于不同的分辨率。

例如,我想在全屏心情下工作,所以我输入了以下代码:

import flash.display.StageDisplayState;
stage.displayState = StageDisplayState.FULL_SCREEN ;

.SWF 文件全屏运行时,该功能不起作用。

当我在键盘上按“Esc”退出全屏情绪时,该功能正常工作。

另外,如果我调整了 .SWF 文件的窗口大小,该功能将不再起作用!!

这是一个很棒的功能,易于使用,我真的很需要它..但我不知道它为什么会出现这种奇怪的行为!

函数是:

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;
}

更新:我做了一个简单的试验项目来测试功能,但问题仍然存在。在项目中,你会发现两颗星。其中一个可以拖动。当两颗星星相互碰撞时,会出现一个文字。但是当我重新调整窗口大小以使其更大时,文本根本不会出现! 这是链接:

http://www.fileconvoy.com/dfl.php?id=g43d4a989bccefabb99964751142bbc6fb6af8d9e4

【问题讨论】:

  • 我不确定你的项目还有什么问题,但我只是尝试了碰撞方法,它在全屏和普通模式下都有效。
  • @Dimitris 我创建了一个新的测试项目,以了解问题是由于我的主项目还是由于功能。但问题仍然存在。如果你想看我的代码,检查这个问题的更新,你可以下载文件。
  • @Dimitris 在这个问题中:stackoverflow.com/questions/10140737/… tziuka 对最佳答案发表了评论,我认为他指的是同一个问题。在此先感谢:)
  • 哦,我没有好显卡。它是 384 MB 英特尔(不是 Nvidia)。它会导致问题吗?

标签: actionscript-3 flash collision-detection resolution


【解决方案1】:

问题在于碰撞所需的位图绘制。

var matrix:Matrix = object1.transform.concatenatedMatrix;
matrix.translate(-limits.left, -limits.top);

以上代码仅适用于stage.scaleMode等于StageScaleMode.NO_SCALE

所以我们需要计算出正确的矩阵并将其提供给BitmapDatadraw方法。

所以这个 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);

...

【讨论】:

  • 这是一个很棒的解决方案。这是我真正需要的……非常感谢……我做了一些小的改动,因为我可以在屏幕上看到名为“collisionDrawingHelper”的孩子,所以我输入了以下代码:collisionDrawingHelper.visible = false ;跨度>
  • 另外,我改变了 object2 的代码,就像你告诉我的 object1 image.draw(object2, getCorrectMatrix(object2, limits), new ColorTransform(1, 1, 1, 1, 255, 255, 255, 容差), BlendMode.DIFFERENCE);
  • 再次非常感谢您,您帮了我很多,您应该得到的不仅仅是最佳答案:) :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
相关资源
最近更新 更多