zoukankan      html  css  js  c++  java
  • 54、Android 粒子效果之雨(下雨的效果)

    核心内容:
    1.绘制下雨场景的个体、雨点(直线)
    2.让直线动起来
    3.处理边界问题
    4.构造雨点对象
    5.雨点大小设置
    6.速度设置和角度设置等
    7.添加多个雨点
    8.抽离可以在 XML 中影响的属性
    9.在代码中解析样式属性并使用其控制雨点变化

    import android.content.Context;
    import android.graphics.Canvas;
    import android.util.AttributeSet;
    import android.view.View;
    
    /**
     * 基类
     */
    public abstract class BaseView extends View {
        private MyThread thread;
        private boolean running = true;
    
        public BaseView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public BaseView(Context context) {
            super(context);
        }
    
        protected abstract void drawSub(Canvas canvas);
        protected abstract void logic();
        protected abstract void init();
        
        class MyThread extends Thread {
            @Override
            public void run() {
                init();
                while (running) {
                    logic();
                    postInvalidate();
                    try {
                        Thread.sleep(30);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        @Override
        protected final void onDraw(Canvas canvas) {
            if (thread == null) {
                thread = new MyThread();
                thread.start();
            } else {
                drawSub(canvas);
            }
        }
    
        @Override
        protected void onDetachedFromWindow() {
            running = false;
            super.onDetachedFromWindow();
        }
    
    }

    1)简单描述单个雨点的行为。

    绘制下雨场景的个体,雨点(直线);

    让直线动起来;

    处理边界问题;

    1 <com.rain.RainView
    2         android:layout_width="match_parent"
    3         android:layout_height="match_parent"
    4         android:background="#ff000000"
    5        />
     1   import android.content.Context;
     2 import android.graphics.Canvas;
     3 import android.graphics.Paint;
     4 import android.util.AttributeSet;
     5 
     6 public class RainView extends BaseView {
     8     private float startX;
     9     private float startY;
    10     private float stopX;
    11     private float stopY;
    12     private float sizeX;
    13     private float sizeY;
    14     private Paint paint;
    15 
    16     public RainView(Context context, AttributeSet attrs) {
    17         super(context, attrs);
    19         // 角度。
    20         sizeX = 10;
    21         sizeY = 30;
    22         // 以下是 初始化直线的坐标。
    23         startX = 100;
    24         startY = 0;
    25         // 改变 角度的直线。
    26         stopX = startX + sizeX;
    27         stopY = startY + sizeY;
    28 
    29         paint = new Paint();
    30         // 把直线 设置成白色。
    31         paint.setColor(0xffffffff);
    32     }
    33 
    34     public RainView(Context context) {
    35         super(context);
    36     }
    37 
    38     @Override
    39     protected void drawSub(Canvas canvas) {
    40         // 绘制一条直线
    41         canvas.drawLine(startX, startY, stopX, stopY, paint);
    42     }
    43 
    44     @Override   /* 让直线动起来 **/ 
    45     protected void logic() {
    46 
    47         //倍率,通过倍率来改变速度。
    48         float opt = 0.5f;
    49 
    50         startX += sizeX * opt;
    51         stopX += sizeX * opt;
    52 
    53         startY += sizeY * opt;
    54         stopY += sizeY * opt;
    55 
    56         // 当直线走出屏幕的时候,变为初始位置。
    57         if (startY > getHeight()) {
    58             startX = 100;
    59             startY = 0;
    60             stopX = startX + 10;
    61             stopY = startY + 30;
    62         }
    63     }
    64 
    65 }

    2)完善雨点行为和构造下雨场景。

    构造雨点对象;

    雨点大小设置;

    速度设置;

    角度设置等 添加多个雨点;

    1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2     android:layout_width="match_parent"
    3     android:layout_height="match_parent" >
    4     <com.rain.RainView
    5         android:layout_width="match_parent"
    6         android:layout_height="match_parent"
    7         android:background="#ff000000" />
    8 </FrameLayout>
     1 public class RainView extends BaseView {
     2     // 多个 “雨点” 对象。
     3     private ArrayList<RainItem> list = new ArrayList<RainItem>();
     4     private int rainNum = 80;  // “雨点”个数。
     5 
     6     public RainView(Context context, AttributeSet attrs) {
     7         super(context, attrs);
     8     }
     9 
    10     public RainView(Context context) {
    11         super(context);
    12     }
    13 
    14     @Override
    15     protected void drawSub(Canvas canvas) {
    16         for (RainItem item : list) {
    17             item.draw(canvas);
    18         }
    19     }
    20 
    21     @Override
    22     protected void logic() {
    23         for (RainItem item : list) {
    24             item.move();
    25         }
    26     }
    27 
    28     @Override
    29     protected void init() {
    30         for (int i = 0; i < rainNum; i++) {
    31             RainItem item = new RainItem(getWidth(), getHeight());
    32             list.add(item);
    33         }
    34     }
    35 
    36 }
     1 /**
     2  * 抽象出一个 雨点 的类
     3  */
     4 public class RainItem {
     5     private int width;
     6     private int height;
     7 
     8     private float startX;
     9     private float startY;
    10     private float stopX;
    11     private float stopY;
    12     private float sizeX;
    13     private float sizeY;
    14     private float opt;  // 速率
    15     private Paint paint;
    16     private Random random;  // 随机数
    17 
    18     // 自定义“雨点”的 宽 和 高
    19     public RainItem(int width, int height) {
    20         this.width = width;
    21         this.height = height;
    22         init();
    23     }
    24 
    25     private void init() {
    26         random = new Random();
    27         // 角度 "X和Y随机。
    28         sizeX = 1 + random.nextInt(10);
    29         sizeY = 10 + random.nextInt(20);
    30         // "雨点"X和Y随机位置。
    31         startX = random.nextInt(width);
    32         startY = random.nextInt(height);
    33         stopX = startX + sizeX;
    34         stopY = startY + sizeY;
    35         // 速率随机。
    36         opt = 0.2f + random.nextFloat();
    37         paint = new Paint();
    38         
    39         paint.setColor(0xffffffff);
    40     }
    41 
    42     public void draw(Canvas canvas) {
    43         canvas.drawLine(startX, startY, stopX, stopY, paint);
    44     }
    45 
    46     public void move() {
    47         startX += sizeX * opt;
    48         stopX += sizeX * opt;
    49 
    50         startY += sizeY * opt;
    51         stopY += sizeY * opt;
    52 
    53         if (startY > height) {
    54             init();
    55         }
    56     }
    57 
    58 }

    3)在xml中定义可以控制下雨的属性。

    抽离可以在xml中影响的属性;

    在代码中解析样式属性并使用其控制雨点变化;

    res/values/attrs.xml

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <resources>
     3     <declare-styleable name="RainView">
     4         <!-- 雨点数量 -->
     5         <attr name="rainNum" format="integer"/>
     6         <!-- 雨点大小 -->
     7         <attr name="size" format="integer"/>
     8         <!-- 雨点颜色 -->
     9         <attr name="rainColor" format="integer"/>
    10         <!-- 雨点颜色随机 -->
    11         <attr name="randColor" format="boolean"/>
    12     </declare-styleable>
    13 </resources>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:rain="http://schemas.android.com/apk/res/com.jikexueyuan.rain"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <com.rain.RainView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#ff000000"
            rain:rainNum="50"
            rain:size="20"
            rain:rainColor="0xff00ff00"
            rain:randColor="true"/>
    </FrameLayout>
     1 public class RainView extends BaseView {
     3     // 多个 “雨点” 对象。
     4     private ArrayList<RainItem> list = new ArrayList<RainItem>();
     5     // 以下4个值,均为默认值。
     6     private int rainNum = 80;  // “雨点”个数。
     7     private int size;
     8     private int rainColor;
     9     private boolean randColor;
    10 
    11     public RainView(Context context, AttributeSet attrs) {
    12         super(context, attrs);
    13 
    14         // 加载,解析 样式属性。res/values/attrs.xml
    15         TypedArray ta = context.obtainStyledAttributes(attrs,
    16                 R.styleable.RainView);
    17 
    18         rainNum = ta.getInteger(R.styleable.RainView_rainNum, 80);
    19         size = ta.getInteger(R.styleable.RainView_size, 20);
    20         rainColor = ta.getInteger(R.styleable.RainView_rainColor, 0xffffffff);
    21         randColor = ta.getBoolean(R.styleable.RainView_randColor, false);
    22         ta.recycle();
    23     }
    24 
    25     public RainView(Context context) {
    26         super(context);
    27     }
    28 
    29     @Override
    30     protected void drawSub(Canvas canvas) {
    31         for (RainItem item : list) {
    32             item.draw(canvas);
    33         }
    34     }
    35 
    36     @Override
    37     protected void logic() {
    38         for (RainItem item : list) {
    39             item.move();
    40         }
    41     }
    42 
    43     @Override
    44     protected void init() {
    45         for (int i = 0; i < rainNum; i++) {
    46             RainItem item = new RainItem(getWidth(), getHeight(), size,
    47                     rainColor, randColor);
    48             list.add(item);
    49         }
    50     }
    51 
    52 }
     1 /**
     2  * 抽象出一个 雨点 的类
     3  */
     4 public class RainItem {
     5 
     6     private int width;
     7     private int height;
     8 
     9     private float startX;
    10     private float startY;
    11     private float stopX;
    12     private float stopY;
    13     private float sizeX;
    14     private float sizeY;
    15     private float opt;  // 速率
    16     private Paint paint;
    17     private Random random;  // 随机数
    18 
    19     private int size = 20;
    20     private int color;
    21     // 随机 雨点颜色 
    22     private boolean randColor = false;;
    23 
    24     // 自定义“雨点”的 宽 和 高
    25     public RainItem(int width, int height) {
    26         this.width = width;
    27         this.height = height;
    28         init();
    29     }
    30 
    31     public RainItem(int width, int height, int size) {
    32         this.size = size;
    33         this.width = width;
    34         this.height = height;
    35         init();
    36     }
    37 
    38     public RainItem(int width, int height, int size, int color) {
    39         this.color = color;
    40         this.size = size;
    41         this.width = width;
    42         this.height = height;
    43         init();
    44     }
    45 
    46     public RainItem(int width, int height, int size, int color,
    47             boolean randColor) {
    48         this.randColor = randColor;
    49         this.color = color;
    50         this.size = size;
    51         this.width = width;
    52         this.height = height;
    53         init();
    54     }
    55 
    56     private void init() {
    57         random = new Random();
    58         // 角度 "X和Y随机。
    59         sizeX = 1 + random.nextInt(size / 2);
    60         sizeY = 10 + random.nextInt(size);
    61         // "雨点"X和Y随机位置。
    62         startX = random.nextInt(width);
    63         startY = random.nextInt(height);
    64         stopX = startX + sizeX;
    65         stopY = startY + sizeY;
    66         // 速率随机。
    67         opt = 0.2f + random.nextFloat();
    68         paint = new Paint();
    69         if (randColor) {
    70             // 颜色随机值。
    71             int r = random.nextInt(256);
    72             int g = random.nextInt(256);
    73             int b = random.nextInt(256);
    74 
    75             paint.setARGB(255, r, g, b);
    76         } else {
    77             paint.setColor(color);
    78         }
    79     }
    80 
    81     public void draw(Canvas canvas) {
    82         canvas.drawLine(startX, startY, stopX, stopY, paint);
    83     }
    84 
    85     public void move() {
    86         startX += sizeX * opt;
    87         stopX += sizeX * opt;
    88 
    89         startY += sizeY * opt;
    90         stopY += sizeY * opt;
    91 
    92         if (startY > height) {
    93             init();
    94         }
    95     }
    96 
    97 }

    DEMO下载路径:http://download.csdn.net/detail/androidsj/9279741

  • 相关阅读:
    haproxy 2.5 发布
    cube.js sql 支持简单说明
    基于graalvm 开发一个cube.js jdbc driver 的思路
    apache kyuubi Frontend 支持mysql 协议
    oceanbase 资源池删除说明
    基于obd 的oceanbase 扩容说明
    jfilter一个方便的spring rest 响应过滤扩展
    cube.js schema 定义多datasource 说明
    typescript 编写自定义定义文件
    meow 辅助开发cli 应用的工具
  • 原文地址:https://www.cnblogs.com/androidsj/p/4974108.html
Copyright © 2011-2022 走看看