我正在开发一个游戏,但我一直坚持寻找一种方法来计算到距动画片段的点和最近边缘的x和y距离。 例如:
我需要计算每个黑点到动画片段最近边缘之间的距离(动画片段并不总是圆形,而是随机形状)。
我很乐意找到解决方案。谢谢!
答案 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));