码迷,mamicode.com
首页 > 移动开发 > 详细

Android特效--粒子效果之雨

时间:2015-09-02 20:32:52      阅读:405      评论:0      收藏:0      [点我收藏+]

标签:

1. 单个雨点的行为

2. 完善雨点的行为和构造下雨场景

3. 在XML中定义可以控制下雨的属性

------------------------------------------------------

1. 单个雨点的行为: 一条线段在运动

    起始点:startX , startY;

    终止点:stopX,  stopY;

    技术分享

   自定义View的框架类

public abstract class BaseView extends View {

    Thread thread;
    
    public BaseView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BaseView(Context context) {
        super(context);
    }

    @Override
    final protected void onDraw(Canvas canvas) {
        //禁止子类覆盖,用final
        if(thread == null ) {
            thread = new MyThread();
            thread.start();
        } else{
            drawSub(canvas);
        }
    }
    
    protected abstract void logic();
    protected abstract void drawSub(Canvas canvas);

    @Override
    final protected void onDetachedFromWindow() {
        // 离开屏幕时结束
        //onDetachedFromWindow在销毁资源(既销毁view)之后调用
        running = false;
        super.onDetachedFromWindow();
    }
    private boolean running = true;
    class MyThread extends Thread {
        @Override
        public void run() {
            while(running) {
                logic();
                postInvalidate(); //线程中更新绘制,重新调用onDraw方法
                try {
                    Thread.sleep(50); //速度太快肉眼看不到,要睡眠
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

}

    自定义单个雨点RainView

public class RainView extends BaseView {

    private float startX = 0;
    private float startY = 0;  // Start Point
    private float stopX = 0;
    private float stopY = 0;  // Stop Point
    private float sizeX = 0;
    private float sizeY = 0;
    private Paint paint;

    public RainView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public RainView(Context context, AttributeSet attrs) {
        super(context, attrs);
        sizeX = 10;
        sizeY = 30;
        //单个雨点的形状,用线段表示
        startX = 100;
        startY = 0;
        stopX = startX + sizeX;
        stopY = startY + sizeY;
        
        paint = new Paint();
        paint.setColor(0xffffffff);
    }

    @Override
    protected void logic() {
        // 让雨点运动
        float opt = 0.3f;
        startX += sizeX * opt;
        stopX += sizeX * opt;
        startY += sizeY * opt;
        stopY += sizeY * opt;
        
        // 雨点出了屏幕的时候让它回到起始点
        if(startY > getHeight() || startX > getWidth()){
            startX = 100;
            startY = 0;
            stopX = startX + sizeX;
            stopY = startY + sizeY;
        }
    }

    @Override
    protected void drawSub(Canvas canvas) {
        // drawSub 完成绘制操作
        canvas.drawLine(startX, startY, stopX, stopY, paint);
    }

}

     在布局文件中使用

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.carloz.raineffect.MainActivity" >

    <com.carloz.raineffect.v1.single_rain.RainView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ff000000" />

</FrameLayout>

    效果如下:

技术分享 

   

2. 完善雨点的行为和构造下雨场景

技术分享

    2.1 将雨点 效果和 行为 抽象出来

           * 雨点的速度和长度是可变的

           * 雨点的倾斜角度是可变的

           * 雨点的位置是可变的   

public class RainItem {

    private int width;
    private int height;

    public RainItem(int width, int height) {
        this.width = width;
        this.height = height;
        init();
    }

    private float startX = 0;
    private float startY = 0; // Start Point
    private float stopX = 0;
    private float stopY = 0; // Stop Point
    private float sizeX = 0;
    private float sizeY = 0;
    private Paint paint;
    private float opt;
    private Random random;

    public void init() {
        // TODO Auto-generated method stub
        random = new Random();

        sizeX = 1 + random.nextInt(10); // 随机改变雨点的角度
        sizeY = 1 + random.nextInt(20);
        // 单个雨点的形状,用线段表示
        startX = random.nextInt(this.width);
        startY = random.nextInt(this.height); // 随机改变雨点的位置
        stopX = startX + sizeX;
        stopY = startY + sizeY;

        paint = new Paint();
        paint.setColor(0xffffffff);
    }

    public void draw(Canvas canvas) {
        canvas.drawLine(startX, startY, stopX, stopY, paint);
    }

    public void move() {
        // 让雨点运动
        opt = 0.2f + random.nextFloat(); // 随机改变雨点的速度和长度
        startX += sizeX * opt;
        stopX += sizeX * opt;
        startY += sizeY * opt;
        stopY += sizeY * opt;

        // 雨点出了屏幕的时候让它回到起始点
        if (startY > this.height || startX > this.width) {
            startX = random.nextInt(this.width);
            startY = random.nextInt(this.height);
            stopX = startX + sizeX;
            stopY = startY + sizeY;
        }
    }

}

    2.2 定义多个雨点

    在 添加抽象 BaseView 方法: protected abstract void init();

class MyThread extends Thread {
    @Override
    public void run() {
        init();
        while(running) {
            logic();
            postInvalidate(); //线程中更新绘制,重新调用onDraw方法
            try {
                Thread.sleep(50); //速度太快肉眼看不到,要睡眠
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

 

 

public class RainView extends BaseView {

    ArrayList<RainItem> rainList = new ArrayList<RainItem>();
    int size = 80;

    public RainView(Context context) {
        super(context);
    }

    public RainView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void init() {
        // TODO Auto-generated method stub
        for (int i = 0; i < size; i++) {
            RainItem item = new RainItem(getWidth(), getHeight());
            rainList.add(item);
        }
    }

    @Override
    protected void logic() {
        for (RainItem item : rainList) {
            item.move();
        }
    }

    @Override
    protected void drawSub(Canvas canvas) {
        // drawSub 完成绘制操作
        for (RainItem item : rainList) {
            item.draw(canvas);
        }
    }

}

    效果如下:

技术分享

 

3. 在XML中定义可以控制下雨的属性

 

Android特效--粒子效果之雨

标签:

原文地址:http://www.cnblogs.com/carlo/p/4779287.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!