zoukankan      html  css  js  c++  java
  • Android特效--粒子效果之雨

    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中定义可以控制下雨的属性

  • 相关阅读:
    《CLR via C#》读书笔记1 之 CLR的执行模型
    C#中的事件和委托
    优分享VR开源啦,优分享VR是基于Google VR开发的一款手机VR视频资源的聚合软件
    安卓端开源移动浏览器开源项目
    Android客户端发布博客
    博客园的IOS客户端“我的博客园”已发布到AppStore
    博客园的IOS客户端图片展示
    ios在tableview里面加subview后在ip4和ip5上显示不一样的问题
    APP开发手记01(app与web的困惑)
    ios开发3.5和4.0寸屏幕自适应中的一点问题
  • 原文地址:https://www.cnblogs.com/carlo/p/4779287.html
Copyright © 2011-2022 走看看