2017-02-21 17 views
13

Có các quả bóng trong ứng dụng của tôi chỉ bay qua màn hình. Họ vẽ như tôi muốn. Nhưng bây giờ tôi muốn vẽ dấu vết đằng sau chúng.Đường ném bóng Android

Tất cả tôi có thể làm được chỉ vẽ bởi canvas.drawPath cái gì đó như hình sau:

I have it now

Nhưng nó không phải là những gì tôi muốn. Nó cần phải có đuôi nhọn và màu gradient như thế này:

I want that

Tôi không có ý tưởng làm thế nào để làm cho nó. Đã thử BitmapShader - không thể thực hiện điều gì đúng. Xin giúp đỡ.

Code:

Trước hết, có Point lớp cho vị trí trên màn hình:

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

Và dấu vết được lưu giữ như hàng đợi của Point:

private ConcurrentLinkedQueue<Point> trail; 

Nó doesn cho dù nó có đầy, chỉ biết nó có giới hạn kích thước:

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

Và vẽ xảy ra trong DrawTrail phương pháp:

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

Bằng cách này, trailPaint là sơn chỉ thực sự chất béo :)

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

Đăng mã của bạn ít nhất – Dimezis

+0

đã làm @Dimezis – Ircover

+0

@Tạo ra bạn có thể đăng mã hoàn chỉnh để tôi có thể tái tạo sự cố không. – Gattsu

Trả lời

0

Tôi đã tìm thấy giải pháp. Nhưng vẫn nghĩ nó không phải là tốt nhất.

Trước hết, có các trường lớp của tôi được sử dụng cho tác vụ đó.

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; 

đối tượng để chia nhỏ đường dẫn tới nhiều phần bằng nhau.

Sau khi điền vào đối tượng mảng đường kẻ được thêm vào cuộc gọi của hàm tính toán đường.

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

Sau đó, chức năng 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]); 
    } 
} 

Nó được tách khỏi chủ đề vẽ. Mã tiếp theo là chức năng vẽ.

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

Điểm chính của bản vẽ này là vẽ theo các phần bằng các loại sơn khác nhau. Gần hơn để bóng - rộng hơn đường mòn. Tôi nghĩ rằng tôi sẽ tối ưu hóa nó, nhưng nó là allready làm việc.

Nếu bạn muốn xem nó trông như thế nào, hãy cài đặt my app from google play.

2

Tôi thấy bạn muốn xem một gradient on the ball đường dẫn, bạn có thể sử dụng một cái gì đó như thế này

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

Đây là những gì bạn nên thay đổi trailPaint của bạn để xem nếu nó hoạt động.

được cung cấp từ here.

+0

Tôi không cần gradient cho bóng. Gradient nên cho đường mòn bóng. – Ircover

+0

Tôi đã chỉnh sửa nhận xét của mình. – Destry

Các vấn đề liên quan