本文介绍一个在google play上很火爆,好玩的App,如题

如图:

实现思路

Android在一个透明的Activity上用SurfaceView绘制闪电,同时加上震动和音效。

在touch事件中调用闪电算法

SurfaceView是一个继承自View的类,可以直接从内存或者DMA等硬件接口取得图像数据,是个非常重要的绘图视图。

SurfaceView特性:可以在主线程之外的线程上绘制视图,而且不会影响主线程,常用于游戏开发。

SurfaceViews使用步骤

继承SurfaceView类

实现SurFaceViewHolder.CallBack接口、有必要的话实现Runnable接口(在run方法中持续的进行视图绘制,该app有点特殊,是在touch事件中绘制视图)然后在线程中进行绘制。

重写:

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {//大小改变时

}@Override
public void surfaceCreated(SurfaceHolder arg0) {//创建时
// mThread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {//销毁时

}



闪电算法


所谓的闪电算法就是在两点之间随机的找出很多很多点,然后把这些点连接起来。那么找点的依据是什么呢?我先说一下我之前的的错误算法:两点之间连线的的附近找,根据两点之间连线的斜率求垂线,在这些垂线上求随机点,然后把这些随机点排序之后连接起来,我拿一张图片解释一下(这是错误算法,google play上有一部分类似app都是按照这种错误算法来的,为什么错?因为太假,太不像)。

种方式实的线条太生硬,拐弯拐的很突然



那么正确的闪电算法是怎么算的呢?

递归

就是在两点坐标P1(X1,Y1),P2(X2,Y2)之间先求中间点X1,X2的中间点X,Y1,Y2的中间点Y,给X一个随机的偏移量,也给Y一个偏移量。X,Y的偏移量包括了正方向和负方向的偏移量,这些偏移都是在一定范围内的随机值,这是生成的 P3(X,Y)就是求得的第一个点,这个点的位置大概就在P1,P2连线中间的一个限定范围的随机半径的圆内。之后就要用递归了,分别在P1(X1,Y1)-->P3(X,Y)和P3(X,Y)-->P2(X2,Y2)重复刚才的计算。拿什么时候跳出递归呢?这也是随机的,我们生成了两个随机数来比较大小,根据大小来判断是否跳出。跳出的时候执行canvas.drawLine(x1,y1,x2,y2);画出一条线。如此,很自然的闪电路径就生成了。

如图:

示例代码drawLine(x1,y1,x2,y2,random,canvas),要先定义好画笔。

public void drawLightning(float x1, float y1, float x2, float y2,
int paramInt, Canvas paramCanvas) {
Random localRandom = new Random();
if (paramInt < localRandom.nextInt(7)) {
paramCanvas.drawLine(x1, y1, x2, y2, mLighnitngColorPaint);
paramCanvas.drawLine(x1, y1, x2, y2, mLighnitngColorPaint);
paramCanvas.drawLine(x1, y1, x2, y2, mLighnitngGlowPaintBold);
return;
}
float x3 = 0, y3 = 0;
if (localRandom.nextBoolean()) {
x3 = (float) ((x2 + x1) / 2.0F + ((localRandom.nextInt(8) - 0.5D) * paramInt));
} else {
x3 = (float) ((x2 + x1) / 2.0F - ((localRandom.nextInt(8) - 0.5D) * paramInt));
}
if (localRandom.nextBoolean()) {
y3 = (float) ((y2 + y1) / 2.0F + ((localRandom.nextInt(5) - 0.5D) * paramInt));
} else {
y3 = (float) ((y2 + y1) / 2.0F - ((localRandom.nextInt(5) - 0.5D) * paramInt));
}
drawLightning(x1, y1, x3, y3, paramInt / 2, paramCanvas);
drawLightning(x2, y2, x3, y3, paramInt / 2, paramCanvas);
return;

}



画出路径之后想要效果更加逼真有发光效果的的话还要利用setMaskFilter来画,我在画一条线的时候,分别用三个画笔在一条轨迹上画三次

第一遍用细线画

第二遍用宽一点,颜色重的setMaskFilter来画

第三遍用比第二遍还宽,但颜色轻的setMaskFilter来画

三次轨迹重叠在一起就有了电流在黑夜中发光的效果

Github:https://github.com/OneHead/electric_screen2D



更多相关文章

  1. Android暑期实习面经部分笔试记录(一)
  2. Android(安卓)不规则封闭区域填充 手指秒变油漆桶
  3. C语言的函数递归(下)
  4. Android(安卓)LruCache原理及使用(对象软引用不行,使用LRU算法)
  5. Android进程调度之adj算法
  6. 算法移植优化(一)android 学习笔记
  7. Android设计模式系列—策略模式
  8. Lan给您分享的岗位信息(Android)
  9. android 学习之图像处理系统(一)

随机推荐

  1. JavaScript 逆向爬取实战(下)
  2. 骚操作!嵌套 JSON 秒变 Dataframe!
  3. PMP证书获得历程
  4. 如何实时主动监控你的网站接口是否挂掉并
  5. 再见 VBA!神器工具统一 Excel 和 Python
  6. Python分析5000+抖音大V,发现大家都喜欢这
  7. 原来炫酷的可视化地图,用Python就能搞定!
  8. 太骚了!Python模型完美切换SAS,还能这么玩
  9. pandas100个骚操作:变量类型自动转换
  10. Android(安卓)View中的onMeasure()方法详