安卓绘制球体轨迹

14

我的应用中有些球只是在屏幕上飞来飞去。 它们的绘制效果我已经满意了,但现在我想在它们后面绘制轨迹。

我能做的仅仅是通过canvas.drawPath绘制类似下图的东西:

I have it now

但这并不是我想要的。 它应该有指向尾巴和渐变颜色,就像这样:

I want that

我不知道如何做到。 尝试过BitmapShader - 没能得到正确的结果。请帮忙。

代码:

首先,这里有一个用于在显示器上定位位置的Point类:

class Point {
    float x, y;
    ...
}

轨迹以Point队列形式存储:

private ConcurrentLinkedQueue<Point> trail;

无论如何填充,只需知道它有大小限制:

trail.add(position);
if(trail.size() > TRAIL_MAX_COUNT) {
    trail.remove();
}

绘制发生在DrawTrail方法中:

private void DrawTrail(Canvas canvas) {
    trailPath.reset();
    boolean isFirst = true;
    for(Point p : trail) {
        if(isFirst) {
            trailPath.moveTo(p.x, p.y);
            isFirst = false;
        } else {
            trailPath.lineTo(p.x, p.y);
        }
    }
    canvas.drawPath(trailPath, trailPaint);
}

顺便说一下,trailPaint只是一种非常浓稠的油漆 :)

trailPaint = new Paint();
trailPaint.setStyle(Paint.Style.STROKE);
trailPaint.setColor(color);
trailPaint.setStrokeWidth(radius * 2);
trailPaint.setAlpha(150);

3
发布你的代码,至少要贴出来。 - Dimezis
完成了 @Dimezis - Ircover
@Ircover,你能否发布完整的代码,以便我可以复制问题。 - Maveňツ
2个回答

3

我看到您希望在球的路径上看到渐变效果,您可以使用类似以下代码:

 int x1 = 0, y1 = 0, x2 = 0,  y2 = 40;
 Shader shader = new LinearGradient(0, 0, 0, 40, Color.WHITE, Color.BLACK, TileMode.CLAMP);
trailPaint = new Paint(); 
trailPaint.setShader(shader); 

这是你应该更改 trailPaint 的代码,看看是否有效。源自这里

我不需要球的渐变。渐变应该是用于球的拖尾。 - Ircover

1
我找到了解决方案。但仍然认为这不是最好的解决方案。
首先,这是我用于完成此任务的类字段。
static final int TRAIL_MAX_COUNT = 50; //maximum trail array size
static final int TRAIL_DRAW_POINT = 30; //number of points to split the trail for draw

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

这个主要是通过不同的颜色分段绘制轨迹。越接近球,轨迹越宽。我认为我会进行优化,但已经可以使用了。
如果您想看看它的效果,请安装我的谷歌应用程序

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接