Android-трейлер

В моем приложении есть шары, которые просто пролетают через дисплей. Они рисуют, как я хочу. Но теперь я хочу проследить за ними.

Все, что я мог сделать, это просто рисовать canvas.drawPath примерно следующим образом:

У меня сейчас

Но это не то, что я хочу. Он должен иметь указанный хвост и цвет градиента следующим образом:

Я хочу чтобы

Я понятия не имею, как это сделать. Пробовал 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(px, py); isFirst = false; } else { trailPath.lineTo(px, py); } } canvas.drawPath(trailPath, trailPaint); } 

Кстати, trailPaint – это просто толстая краска 🙂

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

Solutions Collecting From Web of "Android-трейлер"

Я вижу, что вы хотите увидеть градиент на шаре, вы можете использовать что-то вроде этого

  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 и посмотреть, работает ли он.

Отсюда .

Я нашел решение. Но все же думайте, что это не самый лучший.

Прежде всего, для этой задачи используются поля класса.

 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 для разделения пути на несколько равных частей.

После заполнения объекта массива trail добавлен вызов функции вычисления траектории.

 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(px, py); trailPoss[0][0] = px; trailPoss[0][1] = py; isFirst = false; } else { trailPath.lineTo(px, py); } } 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; } } } 

Главным моментом этого является рисование следов по частям с разными красками. Ближе к мячу – шире след. Я думаю, что буду оптимизировать его, но он уже работает.

Если вы хотите посмотреть, как это выглядит, просто установите мое приложение из игры Google .