我找到了解决方案。但仍然认为这不是最好的解决方案。
首先,这是我用于完成此任务的类字段。
static final int TRAIL_MAX_COUNT = 50;
static final int TRAIL_DRAW_POINT = 30;
private ConcurrentLinkedQueue<Point> trail;
private Paint[] trailPaints;
private float[][] trailPoss, trailTans;
private Path trailPath;
除了使用
trailPath
对象外,我还使用了
PathMeasure
对象将路径分成多个等长部分。
在填充轨迹数组对象后,添加了轨迹计算函数的调用。
lastTrailAdd = now;
trail.add(pos.Copy());
if (trail.size() > TRAIL_MAX_COUNT) {
trail.remove();
}
FillTrail();
然后是我的
FillTrail
函数。
private void FillTrail() {
trailPath.reset();
boolean isFirst = true;
for(Point p : trail) {
if(isFirst) {
trailPath.moveTo(p.x, p.y);
trailPoss[0][0] = p.x;
trailPoss[0][1] = p.y;
isFirst = false;
} else {
trailPath.lineTo(p.x, p.y);
}
}
PathMeasure path = new PathMeasure(trailPath, false);
float step = path.getLength() / TRAIL_DRAW_POINT;
for(int i=0; i<TRAIL_DRAW_POINT; i++) {
path.getPosTan(step * i, trailPoss[i], trailTans[i]);
}
}
它与绘图线程分离。下一段代码是绘图函数。
private void DrawTrail(Canvas canvas) {
if(trail.size() > 1) {
float prevWidthHalfX = 0f, prevWidthHalfY = 0f, prevX = 0f, prevY = 0f;
Path trailStepRect = new Path();
boolean isFirst = true;
for (int i = 0; i < TRAIL_DRAW_POINT; i++) {
float currWidthHalf = (float) (radius) * i / TRAIL_DRAW_POINT / 2f,
currWidthHalfX = currWidthHalf * trailTans[i][1],
currWidthHalfY = currWidthHalf * trailTans[i][0],
currX = trailPoss[i][0], currY = trailPoss[i][1];
if (!isFirst) {
trailStepRect.reset();
trailStepRect.moveTo(prevX - prevWidthHalfX, prevY + prevWidthHalfY);
trailStepRect.lineTo(prevX + prevWidthHalfX, prevY - prevWidthHalfY);
trailStepRect.lineTo(currX + currWidthHalfX, currY - currWidthHalfY);
trailStepRect.lineTo(currX - currWidthHalfX, currY + currWidthHalfY);
canvas.drawPath(trailStepRect, trailPaints[i]);
} else {
isFirst = false;
}
prevX = currX;
prevY = currY;
prevWidthHalfX = currWidthHalfX;
prevWidthHalfY = currWidthHalfY;
}
}
}
这个主要是通过不同的颜色分段绘制轨迹。越接近球,轨迹越宽。我认为我会进行优化,但已经可以使用了。
如果您想看看它的效果,请安装
我的谷歌应用程序。