Android营造雪花和雨滴浪漫效果

时间:2022-03-19 08:58:33

本文在实现雪花效果的基础上,根据漫天飞舞雪花,实现下雨天场景的效果,使用eclipse android 版本,具体内容如下

雪花效果图:

Android营造雪花和雨滴浪漫效果

具体代码:

1、漫天飞舞的雪花主要代码
snowview

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<span style="font-size:14px;">package com.ex</span>ample.snowflake.view;
 
import android.content.context;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.util.attributeset;
import android.view.view;
 
/**
 * 雪花视图, delay时间重绘, 绘制num_snowflakes个雪花
 */
public class snowview extends view {
 
 private static final int num_snowflakes = 150; // 雪花数量
 private static final int delay = 5; // 延迟
 private snowflake[] msnowflakes; // 雪花
 
 public snowview(context context) {
 super(context);
 }
 
 public snowview(context context, attributeset attrs) {
 super(context, attrs);
 }
 
 public snowview(context context, attributeset attrs, int defstyleattr) {
 super(context, attrs, defstyleattr);
 }
 
 @override
 protected void onsizechanged(int w, int h, int oldw, int oldh) {
 super.onsizechanged(w, h, oldw, oldh);
 if (w != oldw || h != oldh) {
  initsnow(w, h);
 }
 }
 
 private void initsnow(int width, int height) {
 paint paint = new paint(paint.anti_alias_flag); // 抗锯齿
 paint.setcolor(color.white); // 白色雪花
 paint.setstyle(paint.style.fill); // 填充;
 msnowflakes = new snowflake[num_snowflakes];
 //msnowflakes所有的雪花都生成放到这里面
 for (int i = 0; i < num_snowflakes; ++i) {
  msnowflakes[i] = snowflake.create(width, height, paint);
 }
 }
 
 @override
 protected void ondraw(canvas canvas) {
 super.ondraw(canvas);
 //for返回snowflake
 for (snowflake s : msnowflakes) {
  //然后进行绘制
  s.draw(canvas);
 }
 // 隔一段时间重绘一次, 动画效果
 gethandler().postdelayed(runnable, delay);
 }
 
 // 重绘线程
 private runnable runnable = new runnable() {
 @override
 public void run() {
  //自动刷新
  invalidate();
 }
 };
}

snowflake

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.example.snowflake.view;
 
import com.example.snowflake.randomgenerator;
 
import android.graphics.canvas;
import android.graphics.paint;
import android.graphics.point;
 
/**
 * 雪花的类, 移动, 移出屏幕会重新设置位置.
 */
public class snowflake {
 // 雪花的角度
 private static final float ange_range = 0.1f; // 角度范围
 private static final float half_angle_range = ange_range / 2f; // 一般的角度
 private static final float half_pi = (float) math.pi / 2f; // 半pi
 private static final float angle_seed = 25f; // 角度随机种子
 private static final float angle_divisor = 10000f;
 // 雪花的移动速度
 private static final float increment_lower = 2f;
 private static final float increment_upper = 4f;
 
 // 雪花的大小
 private static final float flake_size_lower = 7f;
 private static final float flake_size_upper = 20f;
 
 private final randomgenerator mrandom; // 随机控制器
 private final point mposition; // 雪花位置
 private float mangle; // 角度
 private final float mincrement; // 雪花的速度
 private final float mflakesize; // 雪花的大小
 private final paint mpaint; // 画笔
 
 private snowflake(randomgenerator random, point position, float angle, float increment, float flakesize, paint paint) {
 mrandom = random;
 mposition = position;
 mincrement = increment;
 mflakesize = flakesize;
 mpaint = paint;
 mangle = angle;
 }
 
 public static snowflake create(int width, int height, paint paint) {
 randomgenerator random = new randomgenerator();
 int x = random.getrandom(width);
 int y = random.getrandom(height);
 point position = new point(x, y);
 float angle = random.getrandom(angle_seed) / angle_seed * ange_range + half_pi - half_angle_range;
 float increment = random.getrandom(increment_lower, increment_upper);
 float flakesize = random.getrandom(flake_size_lower, flake_size_upper);
 return new snowflake(random, position, angle, increment, flakesize, paint);
 }
 
 // 绘制雪花
 public void draw(canvas canvas) {
 int width = canvas.getwidth();
 int height = canvas.getheight();
 move(width, height);
 canvas.drawcircle(mposition.x, mposition.y, mflakesize, mpaint);
 }
 
 // 移动雪花
 private void move(int width, int height) {
 //x水平方向,那么需要晃动,主要设置这个值就可以,现在取消晃动了
 //如果 mposition.x不加上后面那个值,就不会晃动了
 double x = mposition.x + (mincrement * math.cos(mangle));
 //y是竖直方向,就是下落
 double y = mposition.y + (mincrement * math.sin(mangle));
 
 mangle += mrandom.getrandom(-angle_seed, angle_seed) / angle_divisor;
 //这个是设置雪花位置,如果在很短时间内刷新一次,就是连起来的动画效果
 mposition.set((int) x, (int) y);
 
 // 移除屏幕, 重新开始
 if (!isinside(width, height)) {
  // 重置雪花
  reset(width);
 }
 }
 
 // 判断是否在其中
 private boolean isinside(int width, int height) {
 int x = mposition.x;
 int y = mposition.y;
 return x > mflakesize -5 && x + mflakesize <= width && y >= -mflakesize - 1 && y - mflakesize < height;
 }
 
 // 重置雪花
 private void reset(int width) {
 mposition.x = mrandom.getrandom(width);
 mposition.y = (int) (-mflakesize - 1); // 最上面
 mangle = mrandom.getrandom(angle_seed) / angle_seed * ange_range + half_pi - half_angle_range;
 }
}

2、实现下雨天效果代码
rainview

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.example.raindrop.view;
 
import com.example.raindrop.r;
 
import android.content.context;
import android.graphics.canvas;
import android.graphics.paint;
import android.util.attributeset;
import android.view.view;
 
/**
 * 雨滴视图, delay时间重绘, 绘制num_snowflakes个雨滴
 */
public class rainview extends view {
 
 private static final int num_snowflakes = 150; // 雨滴数量
 private static final int delay = 5; // 延迟
 private rainflake[] msnowflakes; // 雨滴
 
 public rainview(context context) {
 super(context);
 }
 
 public rainview(context context, attributeset attrs) {
 super(context, attrs);
 }
 
 public rainview(context context, attributeset attrs, int defstyleattr) {
 super(context, attrs, defstyleattr);
 }
 
 @override
 protected void onsizechanged(int w, int h, int oldw, int oldh) {
 super.onsizechanged(w, h, oldw, oldh);
 if (w != oldw || h != oldh) {
  initsnow(w, h);
 }
 }
 
 private void initsnow(int width, int height) {
 paint paint = new paint(paint.anti_alias_flag); // 抗锯齿
 paint.setcolor(getresources().getcolor(r.color.colorwater)); // 雨滴的颜色
 paint.setstyle(paint.style.fill); // 填充;
 msnowflakes = new rainflake[num_snowflakes];
 //msnowflakes所有的雨滴都生成放到这里面
 for (int i = 0; i < num_snowflakes; ++i) {
  msnowflakes[i] = rainflake.create(width, height, paint);
 }
 }
 
 @override
 protected void ondraw(canvas canvas) {
 super.ondraw(canvas);
 //for返回snowflake
 for (rainflake s : msnowflakes) {
  //然后进行绘制
  s.draw(canvas);
 }
 // 隔一段时间重绘一次, 动画效果
 gethandler().postdelayed(runnable, delay);
 }
 
 // 重绘线程
 private runnable runnable = new runnable() {
 @override
 public void run() {
  //自动刷新
  invalidate();
 }
 };
}

rainflake

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.example.raindrop.view;
 
import com.example.raindrop.randomgenerator;
 
import android.graphics.canvas;
import android.graphics.paint;
 
/**
 * 雨滴的类, 移动, 移出屏幕会重新设置位置.
 */
public class rainflake {
 
 // 雨滴的移动速度
 private static final float increment_lower = 6f;
 private static final float increment_upper = 8f;
 
 // 雨滴的大小
 private static final float flake_size_lower = 2f;
 private static final float flake_size_upper = 5f;
 
 private final float mincrement; // 雨滴的速度
 private final float mflakesize; // 雨滴的大小
 private final paint mpaint; // 画笔
 
 private line mline; // 雨滴
 
 private randomgenerator mrandom;
 
 private rainflake(randomgenerator random,line line, float increment, float flakesize, paint paint) {
 mrandom = random;
 mline = line;
 mincrement = increment;
 mflakesize = flakesize;
 mpaint = paint;
 }
 
 //生成雨滴
 public static rainflake create(int width, int height, paint paint) {
 randomgenerator random = new randomgenerator();
 int [] nline;
 nline = random.getline(width, height);
  
 line line = new line(nline[0], nline[1], nline[2], nline[3]);
 float increment = random.getrandom(increment_lower, increment_upper);
 float flakesize = random.getrandom(flake_size_lower, flake_size_upper);
 return new rainflake(random,line, increment, flakesize, paint);
 }
 
 // 绘制雨滴
 public void draw(canvas canvas) {
 int width = canvas.getwidth();
 int height = canvas.getheight();
 drawline(canvas, width, height);
 }
 
 /**
 * 改成线条,类似于雨滴效果
 * @param canvas
 * @param width
 * @param height
 */
 private void drawline(canvas canvas, int width, int height) {
 //设置线宽
 mpaint.setstrokewidth(mflakesize);
 //y是竖直方向,就是下落
 double y1 = mline.y1 + (mincrement * math.sin(1.5));
 double y2 = mline.y2 + (mincrement * math.sin(1.5));
 
 //这个是设置雨滴位置,如果在很短时间内刷新一次,就是连起来的动画效果
 mline.set(mline.x1,(int) y1,mline.x2 ,(int) y2);
  
 if (!isinsideline(height)) {
  resetline(width,height);
 }
  
 canvas.drawline(mline.x1, mline.y1, mline.x2, mline.y2, mpaint);
 }
 
 // 判断是否在其中
 private boolean isinsideline(int height) {
 return mline.y1 < height && mline.y2 < height;
 }
 
 // 重置雨滴
 private void resetline(int width, int height) {
 int [] nline;
 nline = mrandom.getline(width, height);
 mline.x1 = nline[0];
 mline.y1 = nline[1];
 mline.x2 = nline[2];
 mline.y2 = nline[3];
 }
 
}

雨滴效果图:

Android营造雪花和雨滴浪漫效果

以上就是本文的全部内容,帮助大家轻松实现浪漫的雪花雨滴效果,大家可以把效果运用到自己的项目中,希望大家喜欢。