获取点和动画片段之间的距离

时间:2018-10-25 18:02:55

标签: actionscript-3 flash actionscript

我正在开发一个游戏,但我一直坚持寻找一种方法来计算到距动画片段的点和最近边缘的x和y距离。 例如: Example

我需要计算每个黑点到动画片段最近边缘之间的距离(动画片段并不总是圆形,而是随机形状)。

我很乐意找到解决方案。谢谢!

1 个答案:

答案 0 :(得分:2)

我怀疑(尽管会被证明是错误的)如果没有有关形状的几何数据,基于像素的操作可能是唯一的方法。

如果有几何数据,则可能只需线性检查点与形状中每个其他点之间的距离(想到的第一个幼稚解决方案-在那里最好的解决方案)。

即使形状是用户生成的(例如绘图),也可以在绘图期间对点进行采样以获取点数据,依此类推。我把它放在一边,因为我认为这些方法比我下面的解决方案(仅假设像素)要快/高效。

话虽如此,该解决方案的工作原理是使用BitmapData的hitTest()检查两个形状是否发生碰撞。它几乎没有效率,而且我不久前就醒来,认为这是一次不错的早操。我没有测试任何错误情况(又名,就像该点在形状内一样)。

它的工作原理是从端点开始,并在端点周围绘制越来越大的圆圈,每一步都将其转换为位图并使用BitmapData的hitTest()。当它认为位图是相交/接触时,则围绕该点的圆的半径将是最接近该形状的距离。

但是,可以通过调整“探针/步长”来提高效率(类似于二进制搜索比线性搜索更有效的方式)。但是,我将留给读者(代码注释中的示例)。

import flash.display.Shape;
import flash.geom.Point;
import flash.display.BitmapData;
import flash.display.Bitmap;

// assumptions: the movie clip is currenly the only thing on the stage

// first generate the first BitmapData by taking all the pixels on the stage (which should just contain the movieclip)
var stagePixels:BitmapData = new BitmapData(this.stage.stageWidth, this.stage.stageHeight, true, 0xffffff);
stagePixels.draw(this);


function getDistance(inputPoint:Point):int {

    var currentSearchDistance:int = 1;
    var result:Boolean = false;

    var zeroPoint:Point = new Point(0, 0); // just a common reference point for the hitTest() call
    var pointShape:Shape;

    while(result == false){
        // create the shape and draw the circle around the point
        pointShape = new Shape();
        pointShape.graphics.lineStyle(1);
        pointShape.graphics.drawCircle(inputPoint.x, inputPoint.y, currentSearchDistance);

        // convert to BitmapData
        var pointPixels:BitmapData = new BitmapData(this.stage.stageWidth, this.stage.stageHeight, true, 0xffffff);
        pointPixels.draw(pointShape);

        // left this here to show the steps and what it is doing
        // will slow down stage rendering though since there are potentially a lot of bitmaps being added to the stage
        this.addChild(new Bitmap(pointPixels));

        result = stagePixels.hitTest(zeroPoint, 0xff, pointPixels, zeroPoint);

        // for now, increase the search distance by 1 only, so can return true when it hits the shape for the first time.
        // This can be optimized to take larger steps (and smaller) steps as well with multiple probes.
        // ex:
        // take a big step (+50)... didn't hit shape
        // so take another big step (+50)... hit shape so we know the point is between the first 50 to 100
        // take maybe half a step back (-25)... hit shape, so we know the point is between the first 50 and 75
        // take another half step back (-12)... didn't hit shape so we know the point is between 62 abd 75...etc
        // thus can slowly close in on the result instead of taking every small step (would have tkaen 62+ checks to get to this point vs 5)
        // (and can also decide to quite early for a "good enough" result)
        currentSearchDistance++;
    }
    return currentSearchDistance;
}

var dot:Point = new Point(100, 100); // input point here
trace(getDistance(dot));

edit:决定添加图片以显示其操作。 Decided to add a picture to show what it's doing.