2017-02-21 20 views
13

W mojej aplikacji są kule, które po prostu latają przez wyświetlacz. Rysują, jak chcę. Ale teraz chcę wytyczyć ślad za nimi.Android szlak balowy remis

Wszystko co robię jest tylko rysunek przez canvas.drawPath coś jak na poniższym rysunku:

I have it now

Ale to nie jest to, co chcę. Powinien on mieć spiczasty ogon i kolor gradientu tak:

I want that

nie mam pojęcia jak to zrobić. Próbowałem BitmapShader - nie mogłem zrobić czegoś dobrze. Prosimy o pomoc.

Kod:

Przede wszystkim, nie ma Point klasa dla pozycji na wyświetlaczu:

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

i ścieżka jest przechowywana w kolejce Point:

private ConcurrentLinkedQueue<Point> trail; 

nie robi Nieważne, jak się wypełnia, tylko wiedz, że ma limit rozmiaru:

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

i rysowania się w DrawTrail metody:

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

przy okazji, trailPaint farba jest po prostu naprawdę gruby :)

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

Zamieść swój kod co najmniej – Dimezis

+0

czy to @Dimezis – Ircover

+0

@Ircover możesz przesłać kompletny kod, dzięki czemu będę mógł powtórzyć problem. – Gattsu

Odpowiedz

0

Znalazłem rozwiązanie. Ale nadal uważam, że nie jest najlepszy.

Przede wszystkim są pola moje klasy używane do tego zadania.

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; 

dodatkowo trailPath obiektu kiedyś PathMeasure przedmiotu podzielić ścieżki do wielu równych części.

Po wypełnieniu obiektu tablicy szlaków dodano wywołanie funkcji obliczania śladu.

lastTrailAdd = now; 
trail.add(pos.Copy()); 
if (trail.size() > TRAIL_MAX_COUNT) { 
    trail.remove(); 
} 
FillTrail(); 

Następnie moja funkcja 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]); 
    } 
} 

Oddziela się od wątku rysunkowego. Następny kod jest funkcją rysowania.

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

Głównym celem jest rysowanie śladu po częściach z różnymi farbami. Bliżej piłki - poszerzaj szlak. Myślę, że zoptymalizuję to, ale to już wszystko działa.

Jeśli chcesz obejrzeć, jak to wygląda, po prostu zainstaluj my app from google play.

2

widzę chcesz zobaczyć gradient na piłkę ścieżkę, możesz użyć czegoś podobnego do tego, aby uzyskać coś takiego:

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

To jest powód, dla którego powinieneś zmienić swój szlak i zobaczyć, czy to działa.

dostarczone od here.

+0

Nie potrzebuję gradientu dla piłki. Gradient powinien być dla szlaku piłek. – Ircover

+0

Zmieniłem swój komentarz. – Destry