您的位置:首页 > 其它

粒子动画处理

2015-10-11 23:28 381 查看
闲来无事,某天上网链接到燎原网站(http://liaoyuan.io/)时发现背景的动态效果挺不错的,故移到android上面实现之。代码不也很简单多,直接贴上以供参考。由于是动态刷新,所以使用了surfaceview来处理,用view应该也可以。

网站效果图:



实现效果:





ParticleView.java

import java.util.ArrayList;
 
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
 
public class ParticleViewextends SurfaceView implements SurfaceHolder.Callback {
   public static final int TIME_INTERVAL = 100;
   private DrawThread drawThr;
   private static final int PART_NUM = 20;
   private static final int CIRCLE = 2;
   private static final int COUNTER_DIS = 100;
   private ArrayList<Particle> mParticles;
   private ArrayList<CounterParticle> mCounterPt;
   private int scrWdh, scrHgt;
   private Paint mPtPaint, mLinePaint;
  
   public ParticleView(Context context) {
      super(context);
      init();
   }
 
   private void init() {
      this.getHolder().addCallback(this);
      drawThr = new DrawThread(this, getHolder());
 
      mPtPaint = new Paint();
      mPtPaint.setColor(0xff0791ec);
 
      mLinePaint = new Paint();
      mLinePaint.setColor(0xff00ffff);
   }
 
   private void initData() {
      mParticles = new ArrayList<Particle>();
      mCounterPt = new ArrayList<CounterParticle>();
      for (int i = 0; i < PART_NUM; i++) {
        mParticles.add(new Particle(scrWdh, scrHgt));
      }
 
      getPtCounter();
   }
 
   private void getPtCounter() {
      mCounterPt.clear();
      int end = PART_NUM - 1;
      for (int i = 0; i < end; i++) {
        Particle mLeft = mParticles.get(i);
        for (int j = i + 1; j < PART_NUM; j++) {
           Particle mRight = mParticles.get(j);
           if (Math.abs(mLeft.x - mRight.x) <= COUNTER_DIS
                 && Math.abs(mLeft.y - mRight.y) <= COUNTER_DIS) {
              mCounterPt.add(new CounterParticle(mLeft.x, mLeft.y,
                    mRight.x, mRight.y));
           }
        }
      }
   }
 
   public ParticleView(Context context, AttributeSet attrs) {
      super(context, attrs);
      init();
   }
 
   @Override
   public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
      scrWdh = arg2;
      scrHgt = arg3;
      initData();
   }
 
   @Override
   public void surfaceCreated(SurfaceHolder holder) {
      if (!drawThr.isAlive()) {
        drawThr.start();
      }
   }
 
   @Override
   public void surfaceDestroyed(SurfaceHolder holder) {
      drawThr.isRunning = false;
      drawThr = null;
   }
  
   public void doDraw(Canvas canvas) {
      canvas.drawColor(Color.WHITE);
      // 绘制粒子
      for (int i = 0; i < PART_NUM; i++) {
        canvas.drawCircle(mParticles.get(i).x, mParticles.get(i).y, CIRCLE,
              mPtPaint);
      }
 
      int countSize = mCounterPt.size();
      for (int i = 0; i < countSize; i++) {
        CounterParticle mCurCount = mCounterPt.get(i);
        canvas.drawLines(mCurCount.pts, mLinePaint);
      }
   }
 
   public void changeData() {
      for (int i = 0; i < PART_NUM; i++) {
        Particle mCurPart = mParticles.get(i);
        mCurPart.x += mCurPart.hor_v;
        mCurPart.y += mCurPart.ver_v;
        if (outRange(mCurPart)) {
           mParticles.remove(mCurPart);
           mParticles.add(i, new Particle(scrWdh, scrHgt));
        }
      }
 
      getPtCounter();
   }
 
   private boolean outRange(Particle mCurPart) {
      return mCurPart.x < 0 || mCurPart.x > scrWdh || mCurPart.y < 0
           || mCurPart.y > scrHgt;
   }
}




Particle.java

public class Particle{
   private static int SPEED = 5;
   double ver_v;    //垂直速度
   double hor_v;    //水平速度
   int startX;      //初始X坐标
   int startY;      //初始Y坐标
   int x;           //实时X坐标
   int y;           //实时Y坐标
  
   public Particle(double ver_v, double hor_v, int x, int y) {
      super();
      this.ver_v = ver_v;
      this.hor_v = hor_v;
      this.startX = x;
      this.startY = y;
      this.x = x;
      this.y = y;
   }
  
   public Particle(int scrWdh, int scrHgt) {
      int curX = (int) (Math.random() * scrWdh);
      int curY = (int) (Math.random() * scrHgt);
     
      this.hor_v = checkSpeedAvail(curX, scrWdh);
      this.ver_v = checkSpeedAvail(curY, scrHgt);
      this.startX = this.x = curX;
      this.startY = this.y = curY;
   }
  
   private int checkSpeedAvail(int curPos, int range) {
      int speed = (int) (Math.random() * SPEED);
      speed++;
      return curPos > range / 2 ? -speed : speed;
   }
}




CounterParticle.java

public class CounterParticle{
   float[] pts;
 
   public CounterParticle(int sx, int sy, int ex, int ey) {
      pts = new float[] { sx, sy, ex, ey };
   }
}




DrawThread.java

import android.graphics.Canvas;
import android.view.SurfaceHolder;
 
public class DrawThread extends Thread {
   ParticleViewpv;
   SurfaceHolder suraceHolder;
   boolean isRunning;
   int sleepSpan = 100;
 
   public DrawThread(ParticleView pv, SurfaceHolder suraceHolder) {
      this.isRunning = true;
      this.pv = pv;
      this.suraceHolder = suraceHolder;
   }
 
   @Override
   public void run() {
      Canvas canvas = null;
      while (isRunning) {
        try {
           canvas = suraceHolder.lockCanvas();
           synchronized (suraceHolder) {
              pv.changeData();
              pv.doDraw(canvas);
           }
        } catch (Exception e) {
           e.printStackTrace();
        } finally {
           if (canvas != null) {
              suraceHolder.unlockCanvasAndPost(canvas);
           }
        }
        try {
           Thread.sleep(sleepSpan);// 线程休眠一段时间
        } catch (Exception e) {
           e.printStackTrace();// 捕获并打印异常
        }
      }
   }
 
}




顺带推荐一个录制屏幕gif工具:gifcam
http://pan.baidu.com/s/1mgtjZoG
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: