1. 程式人生 > >實現三星S3蒲公英水波紋效果(三)——Activity水波紋實現篇

實現三星S3蒲公英水波紋效果(三)——Activity水波紋實現篇

修改FallView檔案,主要參考RenderScriptWallpaper和RenderScriptWallpaper中對RenderscriptGL初始化和呼叫的時機,在覆寫的RSSurfaceView指定方法中初始化和呼叫RenderScriptGL。 

FallView.java檔案如下:

/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.harlan.waterscreen;

import android.content.Context;
import android.renderscript.RSSurfaceView;
import android.renderscript.RenderScript;
import android.renderscript.RenderScriptGL;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

class FallView extends RSSurfaceView {
    private FallRS mRender;
    /*******add by Harlan***********************/
    private RenderScriptGL mRs;
    /*******************************************/

    public FallView(Context context) {
        super(context);
        setFocusable(true);
        setFocusableInTouchMode(true);
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        super.surfaceChanged(holder, format, w, h);
//        RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
//        RenderScriptGL RS = createRenderScriptGL(sc);
//        mRender = new FallRS(w, h);
//        mRender.init(RS, getResources(), false);
//        mRender.start();
        /*******add by Harlan***********************/
        if (mRs != null) {
            mRs.setSurface(holder, w, h);
        }
        if (mRender == null) {
            mRender = new FallRS(w, h);
            mRender.init(mRs, getResources(), false);
            mRender.start();
        } else {
            mRender.resize(w, h);
        }
        /*****************************************/
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                mRender.addDrop(event.getX(), event.getY());
                try {
                    Thread.sleep(16);
                } catch (InterruptedException e) {
                    // Ignore
                }
                break;
        }
        return true;
    }
    
    /*******add by Harlan***********************/
   @Override
public void surfaceCreated(SurfaceHolder holder)
{
    super.surfaceCreated(holder);
    //初始化RenderScriptRS
    RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
		if (mRs == null) {
			mRs = createRenderScriptGL(sc);
		}
    mRs.setPriority(RenderScript.Priority.LOW);
}
    
    @Override
    protected void onDetachedFromWindow()
    {
        super.onDetachedFromWindow();
        destroyRenderer();
    }
    
    private void destroyRenderer() {
        if (mRender != null) {
            mRender.stop();
            mRender = null;
        }
        if (mRs != null) {
            mRs.setSurface(null, 0, 0);
            mRs.destroy();
            mRs = null;
        }
    }
    
}

在Fall activity中將FallView設為內容背景。放在我的手機上執行下,發現已經可以實現大致功能,但連續觸屏時,水滴團簇在一塊兒,效果不是很好,而且沒有水滴音效,不是很自然。

如圖:

 

處理下,先加上音效.這裡我使用SoundPool播放音效。SoundPool使用音效池的概念來管理多個短促的音效,在程式中按照音效的ID進行播放。

為了方便管理SoundPool所載入的每個聲音的ID,我使用了一個HashMap<Integer,Integer>物件來管理聲音。(音訊檔案提取自三星9300)

定義需要用到的常量變數:

	public static final int PLAY_DROP_MUSIC = 0x1;
	public static final int PLAY_WATER_MUSIC = 0x2;
	private boolean isPlay;
	private static int sConut;
	private SoundPool mSound;
	private HashMap<Integer, Integer> soundMap;

在surfaceCreated(SurfaceHolder holder)方法中新增:

    mSound = new SoundPool(2, AudioManager.STREAM_RING, 5);
    soundMap = new HashMap<Integer, Integer>();
    soundMap.put(1, mSound.load(getContext(), R.raw.drop, 5));
    soundMap.put(2, mSound.load(getContext(), R.raw.water, 5)); 

在TouchEvent事件中加上音效的播放,並對水波紋addDrop方法呼叫的頻率改進一下,使其自然些。

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            	mSound.play(soundMap.get(1), 5, 5, 0, 0, 1);
            	isPlay = true;
            	sConut = 0;
            	mRender.addDrop(event.getX(), event.getY());
            	break;
            case MotionEvent.ACTION_MOVE:
            	sConut ++;
                if (isPlay){
                mSound.play(soundMap.get(2), 5, 5, 0, 0, 1);
                isPlay = false;
                }
                if (sConut <10){
                mRender.addDrop(event.getX(), event.getY());
                }
                MotionEvent.obtain(event).setAction(MotionEvent.ACTION_UP);
                try {
                    Thread.sleep(150);
                } catch (InterruptedException e) {
                    // Ignore
                }
                break;
        }
        return true;
    }

好了,這時候水波紋的效果就自然很多了。

好了,大致完工了,最後將pond.png圖片置換為三星蒲公英圖片。另外,在Manifest檔案裡面將應用主題設定為全屏顯示。

 android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"

值得注意的是,原始碼楓葉桌布中,河床是圖片的倒影,因此蒲公英也是倒著的,修改下引數,將FallRS.java中String t中的

"  varTex0 = vec2((pos.x + 1.0), (pos.y + 1.6666));\n" +

以及

"  varTex0.xy *= vec2(0.25, 0.33);\n" +

修改為

"  varTex0 = vec2((pos.x +1.2), (-pos.y+1.15));\n" +
"  varTex0.xy *= vec2(0.4, 0.45);\n" +


OK,大功告成,最終效果圖:

最後,貼上附件(三星S3水波紋觸屏效果原始碼):