2014-04-11 168 views
2

我一直在这个好几天没有找到一个好的解决方案(至少对我来说)。安卓绘制动画虚线曲线

基本上我需要做的就是绘制动画虚线,那将是一个导弹弹道一个基本的游戏。该轨迹将接受x,y的开始,中间和最终。我读了许多关于动画曲线甚至直线开始的Q/A,但与我必须做的相比,它们看起来非常复杂。

我有一个onclick监听器触发了导弹发射按钮,但是到现在为止,它只是绘制静态行没有任何动画。

你还记得吗?这就是我想达到的效果: http://www.youtube.com/watch?v=UDc3ZEKl-Wc

香蕉的轨迹不画,但,你有想法。


在这里,从您的范例开始我试图绘制使用数组和循环同步的曲线,但我得到的是,有时,不总是与一个空指针异常应用程序崩溃,不知道为什么。我究竟做错了什么?这里是我的代码:

public class DrawDottedCurve extends View { 

    Path[] path = new Path[8]; 
    Path[] drawingPath = new Path[8]; 
    PathMeasure[] measure = new PathMeasure[8]; 
    Path[] segmentPath = new Path[8]; 
    float[] length = new float[8]; 
    float[] start = new float[8]; 
    float[] percent = new float[8]; 
    Paint paint = new Paint(); 
    float x1; 
    float y1; 
    float x3; 
    float y3; 
    long k = 0; 
    Canvas canvas; 
    Random r = new Random(); 

    public DrawDottedCurve(Context context, int a, int b, int c, int d) { 
     super(context); 
     x1 = a; 
     y1 = b; 
     x3 = c; 
     y3 = d; 

     paint.setAlpha(255); 
     paint.setStrokeWidth(2); 
     paint.setColor(Color.RED); 
     paint.setStyle(Style.STROKE); 
     paint.setPathEffect(new DashPathEffect(new float[] { 2, 4 }, 50)); 

     for (int i = 0; i < 8; i++) { 
      k = r.nextInt(100 - 30) + 30; 
      path[i] = new Path(); 
      path[i].moveTo(x1 + k, y1 + k); // 
      path[i].quadTo((x3 + k - x1 + k)/2, (y3 + k - y1 + k)/2, 
        x3 + k, y3 + k); // Calculate Bezier Curves 
     } 

     final long DRAW_TIME = 10000; 
     CountDownTimer timer = new CountDownTimer(DRAW_TIME, 100) { 

      @Override 
      public void onTick(long millisUntilFinished) { 
       Log.d("Timer", "Inizio"); 
       for (int i = 0; i < 8; i++) { 
        start[i] = 0; 
        measure[i] = new PathMeasure(); 
        measure[i].setPath(path[i], false); 

        percent[i] = ((float) (DRAW_TIME - millisUntilFinished)) 
          /(float) DRAW_TIME; 

        segmentPath[i] = new Path(); 
        drawingPath[i] = new Path(); 
        length[i] = measure[i].getLength() * percent[i]; 
        measure[i].getSegment(start[i], length[i], segmentPath[i], 
          true); 
        start[i] = length[i]; 
        drawingPath[i].addPath(segmentPath[i]); 


       } 
       invalidate(); 
; 
      } 

      @Override 
      public void onFinish() { 
       for (int i = 0; i < 8; i++) { 
        measure[i].getSegment(start[i], measure[i].getLength(), 
          segmentPath[i], true); 
        drawingPath[i].addPath(segmentPath[i]); 


       } 

       invalidate(); 
       Log.d("Timer", "Fine"); 
      } 

     }; 
     timer.start(); 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     for (int i = 0; i < 8; i++) { 
      canvas.drawPath(drawingPath[i], paint); 
      invalidate(); 

     } 

    } 
} 
+0

计算一个曲线上的点,Bezier曲线例如并一个接一个地绘制它们...... – ElDuderino

回答

0

假设你有一个画布上绘制,并要跟踪这个代码应该做的工作,为动画它的路径。

private void init() { 
    missilePath = new Path(); 
    missileDrawPath = new Path(); 

    mPaint = new Paint(); 
    mPaint.setStrokeWidth(3); 
    mPaint.setColor(Color.BLACK); 
    mPaint.setStyle(Style.STROKE); 
    mPaint.setAntiAlias(true); 

    PathEffect dashEffect = new DashPathEffect(new float[] {2, 4}, 0); 
    mPaint.setPathEffect(dashEffect); 

    final long DRAW_TIME = 5000; 
    timer = new CountDownTimer(DRAW_TIME, 100) { 
     PathMeasure measure = new PathMeasure(); 
     Path segmentPath = new Path(); 
     float start = 0; 

     @Override 
     public void onTick(long millisUntilFinished) { 
      measure.setPath(missilePath, false); 
      float percent = ((float) (DRAW_TIME - millisUntilFinished))/(float) DRAW_TIME; 
      float length = measure.getLength() * percent; 
      measure.getSegment(start, length, segmentPath, true); 
      start = length; 
      missileDrawPath.addPath(segmentPath); 
      invalidate(); 
     } 

     @Override 
     public void onFinish() { 
      measure.getSegment(start, measure.getLength(), segmentPath, true); 
      missileDrawPath.addPath(segmentPath); 
      invalidate(); 
     } 
    }; 
    timer.start(); 
} 


@Override 
public void onDraw(Canvas c) { 
    super.onDraw(c); 
    c.drawPath(missileDrawPath, mPaint); 
} 

基本上计时器得到启动,并根据段被从missilePath检索并添加到应当当前绘制的路径所经过的时间。

+0

我将在接下来的几天内实现该代码并让您知道。现在感谢 – realpclaudio

0

谢谢你,真的很好SceLus,这里的人,最终停留在同一个问题的全部代码。

类构造函数采用Bezier曲线起始和最终X和Y的作为输入,并简单地计算中间控制点,则根据SceLus代码绘制的一切。

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.DashPathEffect; 
import android.graphics.Paint; 
import android.graphics.Paint.Style; 
import android.graphics.Path; 
import android.graphics.PathMeasure; 
import android.os.CountDownTimer; 
import android.view.View; 

public class DrawDottedCurve extends View { 

    Path path = new Path(); 
    Path drawingPath = new Path(); 
    Paint paint = new Paint(); 
    float x1; 
    float y1; 
    float x3; 
    float y3; 

    public DrawDottedCurve(Context context, int a, int b, int c, int d) { 
     super(context); 

     x1 = a; 
     y1 = b; 
     x3 = c; 
     y3 = d; 

     paint.setAlpha(255); 
     paint.setStrokeWidth(2); 
     paint.setColor(Color.RED); 
     paint.setStyle(Style.STROKE); 
     paint.setPathEffect(new DashPathEffect(new float[] { 2, 4 }, 50)); 

     path.moveTo(x1, y1); // 
     path.quadTo((x3 - x1)/2, (y3 - y1)/2, x3, y3); // Calculate Bezier Curve 

     final long DRAW_TIME = 10000; 
     CountDownTimer timer = new CountDownTimer(DRAW_TIME, 100) { 
      PathMeasure measure = new PathMeasure(); 
      Path segmentPath = new Path(); 
      float start = 0; 

      @Override 
      public void onTick(long millisUntilFinished) { 
       measure.setPath(path, false); 
       float percent = ((float) (DRAW_TIME - millisUntilFinished)) 
         /(float) DRAW_TIME; 
       float length = measure.getLength() * percent; 
       measure.getSegment(start, length, segmentPath, true); 
       start = length; 
       drawingPath.addPath(segmentPath); 
       invalidate(); 
      } 

      @Override 
      public void onFinish() { 
       measure.getSegment(start, measure.getLength(), segmentPath, 
         true); 
       drawingPath.addPath(segmentPath); 
       invalidate(); 
      } 
     }; 
     timer.start(); 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     canvas.drawPath(drawingPath, paint); 
    } 
}