基本信息
源码名称:Android点击屏幕出现水波纹效果
源码大小:16.83M
文件格式:.zip
开发语言:Java
更新时间:2018-03-05
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
参照:http://blog.csdn.net/Poison_H/article/details/43735445。点击手机屏幕实现水波效果,如下图:
public class WaterWaveView extends SurfaceView implements SurfaceHolder.Callback { // 背景图的宽度和高度 private int backWidth; private int backHeight; /** * buf1 和 buf2是波能缓冲区,分别代表了每个点的前一时刻和后一时刻的波幅数据 */ private short[] buf1; private short[] buf2; private int[] bitmap1; private int[] bitmap2; private Bitmap bgImage = null; // 是否第一次加载 private boolean firstLoad = false; WavingThread wavingThread = new WavingThread(); // 显示一个surface的抽象接口,使你可以控制surface的大小和格式, 以及在surface上编辑像素,和监视surace的改变 SurfaceHolder mSurfaceHolder = null; private int doubleWidth; private int fiveWidth; // 持续时间 private int loopTime; private int bitmapLen; public WaterWaveView(Context context) { super(context); mSurfaceHolder = getHolder(); mSurfaceHolder.addCallback(this); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (!firstLoad) { // 背景图 bgImage = BitmapFactory.decodeResource(this.getResources(), R.drawable.bg); bgImage = Bitmap.createScaledBitmap(bgImage, w, h, false);// 缩放而已 backWidth = bgImage.getWidth(); backHeight = bgImage.getHeight(); buf2 = new short[backWidth * backHeight]; buf1 = new short[backWidth * backHeight]; bitmap2 = new int[backWidth * backHeight]; bitmap1 = new int[backWidth * backHeight]; // 将bgImage的像素拷贝到bitmap1数组中,用于渲染。。。 bgImage.getPixels(bitmap1, 0, backWidth, 0, 0, backWidth, backHeight); bgImage.getPixels(bitmap2, 0, backWidth, 0, 0, backWidth, backHeight); for (int i = 0; i < backWidth * backHeight; i) { buf2[i] = 0; buf1[i] = 0; } doubleWidth = backWidth << 1; fiveWidth = 5 * backWidth; loopTime = ((backHeight - 4) * backWidth) >> 1; bitmapLen = backWidth * backHeight - 1; firstLoad = true; } } class WavingThread extends Thread { boolean running = true; public void setRunning(boolean running) { this.running = running; } @Override public void run() { Canvas c = null; while (running) { c = mSurfaceHolder.lockCanvas(); makeRipple(); doDraw(c); mSurfaceHolder.unlockCanvasAndPost(c); } } } /******************************************************* * 计算波能数据缓冲区 *******************************************************/ private void makeRipple() { int k = fiveWidth; int xoff = 0, yoff = 0; int cp = 0; int tarClr = 0; int i = fiveWidth; while (i < loopTime) { // 波能扩散 buf2[k] = (short) (((buf1[k - 2] buf1[k 2] buf1[k - doubleWidth] buf1[k doubleWidth]) >> 1) - buf2[k]); // 波能衰减 buf2[k] = (short) (buf2[k] - (buf2[k] >> 5)); // 求出该点的左上的那个点xoff,yoff cp = k - doubleWidth - 2; xoff = buf2[cp - 2] - buf2[cp 2]; yoff = buf2[cp - doubleWidth] - buf2[k - 2]; tarClr = k yoff * doubleWidth xoff; if (tarClr > bitmapLen || tarClr < 0) { k = 2; continue; } // 复制象素 bitmap2[k] = bitmap1[tarClr]; k = 2; i; } short[] tmpBuf = buf2; buf2 = buf1; buf1 = tmpBuf; } /***************************************************** * 增加波源 x坐标 y坐标 波源半径 波源能量 *****************************************************/ private void touchWater(int x, int y, int stonesize, int stoneweight) { // 判断坐标是否在屏幕范围内 if (x stonesize > backWidth) { return; } if (y stonesize > backHeight) { return; } if (x - stonesize < 0) { return; } if (y - stonesize < 0) { return; } // 产生波源,填充前导波能缓冲池 int endStoneX = x stonesize; int endStoneY = y stonesize; int squaSize = stonesize * stonesize; int posy = y - stonesize; int posx = x - stonesize; for (posy = y - stonesize; posy < endStoneY; posy) { for (posx = x - stonesize; posx < endStoneX; posx) { if ((posx - x) * (posx - x) (posy - y) * (posy - y) < squaSize) { buf1[backWidth * posy posx] = (short) -stoneweight; } } } } /***************************************************** * 增加波源 x坐标 y坐标 波源半径 波源能量 *****************************************************/ private void trickWater(int x, int y, int stonesize, int stoneweight) { // 判断坐标是否在屏幕范围内 if (x stonesize > backWidth) { return; } if (y stonesize > backHeight) { return; } if (x - stonesize < 0) { return; } if (y - stonesize < 0) { return; } // 产生波源,填充波能缓冲池 int endStoneX = x stonesize; int endStoneY = y stonesize; int posy = y - stonesize; int posx = x - stonesize; for (posy = y - stonesize; posy < endStoneY; posy) { for (posx = x - stonesize; posx < endStoneX; posx) { if (posy >= 0 && posy < backHeight && posx >= 0 && posx < backWidth) { buf1[backWidth * posy posx] = (short) -stoneweight; } } } } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { // 设置波源半径和波源能量 touchWater((int) event.getX(), (int) event.getY(), 200, 300); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { trickWater((int) event.getX(), (int) event.getY(), 200, 300); } return true; } protected void doDraw(Canvas canvas) { /** * Parameters: 1.colors 2.offset 3.stride 4.x 5. y 6.width 7.height * 8.hasAlpha 9. paint */ //绘制 canvas.drawBitmap(bitmap2, 0, backWidth, 0, 0, backWidth, backHeight, false, null); } @Override public void surfaceCreated(SurfaceHolder holder) { wavingThread.setRunning(true); wavingThread.start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { boolean retry = true; wavingThread.setRunning(false); // 非暴力关闭线程,直到此次该线程运行结束之前,主线程停止运行,以防止Surface被重新激活 while (retry) { try { wavingThread.join(); // 阻塞current // Thread(当前执行线程)直到被调用线程(thread)完成。 retry = false; } catch (InterruptedException e) { } } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } }
waterWaveView = new WaterWaveView(this); setContentView(waterWaveView);