Android上的水果忍者刀锋效果(JAVA实现)

显示刀锋的View

package com.wbhuang.myninjia;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

/**
 * @author wbhuang 
 * 20130821
 */
public class ShadeView extends View {
	static final int MAX_POINTS_NUM = 10;
	static final float CENTER_RATIO = 0.5f;
	static final float SHAPE_RATIO = 0.02f;
	
	//点类
	static class Vertex {
		public float x;
		public float y;
		public Vertex() {}
		public Vertex(float x, float y) {
			this.x = x;
			this.y = y;
		}
	}
	
	List<Vertex> leftVertexs = new ArrayList<Vertex>(MAX_POINTS_NUM);	//刀锋上边线点集
	List<Vertex> rightVertexs = new ArrayList<Vertex>(MAX_POINTS_NUM);	//刀锋下边线点集
	List<Vertex> sampleVertexs = new ArrayList<Vertex>(MAX_POINTS_NUM);	//刀锋路径的点集
	
	float shape_width = 10;
	private Paint paint;
	private static final int gestureColor = Color.rgb(153, 153, 153);
	private static final int alpha = 220;
	private static final int alpha_full = 255;
	private static long last_time;
	private static final int MIN_TIME_INTERVAL = 10;
	    
	public ShadeView(Context context) {
		super(context);
		paint = new Paint();
		paint.setStyle(Paint.Style.FILL);
		
		DisplayMetrics metric = new DisplayMetrics();
		((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric);
        int width = metric.widthPixels;
        shape_width = width * SHAPE_RATIO;//刀锋长度
	}
	
	//计算路径上面和下面的点集
	private void calcVertexs() {
		int len = sampleVertexs.size();
		leftVertexs.clear();
		rightVertexs.clear();
		for (int i = 1; i < len; i++) {
			Vertex cur = sampleVertexs.get(i);
			Vertex pre = sampleVertexs.get(i-1);
			
			Vertex center = new Vertex();
			center.x = cur.x - (cur.x - pre.x) * CENTER_RATIO;
			center.y = cur.y - (cur.y - pre.y) * CENTER_RATIO;
			
			float w = cur.x - pre.x;
			float h = cur.y - pre.y;
			double angle = Math.atan(h/w);
			
			Vertex leftVertex = new Vertex();
			Vertex rightVertex = new Vertex();
			
			float centerShapeWidth = shape_width *  i / len;
   
                                                if (i == (len - 2))
                                                                centerShapeWidth = shape_width;			
			if (cur.x > pre.x) {
				leftVertex.x = (float) (center.x + Math.sin(angle) * centerShapeWidth);
				leftVertex.y = (float) (center.y - Math.cos(angle) * centerShapeWidth);
				rightVertex.x = (float) (center.x - Math.sin(angle) * centerShapeWidth);
				rightVertex.y = (float) (center.y + Math.cos(angle) * centerShapeWidth);
			} else {
				rightVertex.x = (float) (center.x + Math.sin(angle) * centerShapeWidth);
				rightVertex.y = (float) (center.y - Math.cos(angle) * centerShapeWidth);
				leftVertex.x = (float) (center.x - Math.sin(angle) * centerShapeWidth);
				leftVertex.y = (float) (center.y + Math.cos(angle) * centerShapeWidth);
			}
			leftVertexs.add(leftVertex);
			rightVertexs.add(rightVertex);
		}
	}
	
	@Override
	public void onDraw(Canvas canvas) {
		Path path = new Path();
		if (sampleVertexs.size() > 1) {
			calcVertexs();
			Vertex begin = sampleVertexs.get(0);
			Vertex end = sampleVertexs.get(sampleVertexs.size()-1);
			
			path.moveTo(begin.x, begin.y);
			for (int i= 0; i < leftVertexs.size(); i++) {
				Vertex vertex = leftVertexs.get(i);
				path.lineTo(vertex.x, vertex.y);
			}
			path.lineTo(end.x, end.y);
			for (int i = rightVertexs.size() - 1; i > 0; i--) {
				Vertex vertex = rightVertexs.get(i);
				path.lineTo(vertex.x, vertex.y);
			}
			
			paint.setColor(Color.WHITE);
            paint.setAlpha(alpha_full);
	        canvas.drawPath(path, paint);
		}
		super.onDraw(canvas);
	}
	@Override
	public boolean onTouchEvent(android.view.MotionEvent event) {
		if(event.getPointerCount() == 1){
			int action = event.getAction();
			if (MotionEvent.ACTION_DOWN == action) {
				leftVertexs.clear();
				rightVertexs.clear();
				sampleVertexs.clear();
			} else if (MotionEvent.ACTION_MOVE == action) {
				//if (event.getEventTime() - last_time > MIN_TIME_INTERVAL) {
					last_time = event.getEventTime();
		         	if (sampleVertexs.size() > MAX_POINTS_NUM) {
		         		sampleVertexs.remove(0);
		         	}
		         	Vertex vertex = new Vertex(event.getX(), event.getY());
		         	sampleVertexs.add(vertex);
				//}
			} else if (MotionEvent.ACTION_UP == action) {
				leftVertexs.clear();
				rightVertexs.clear();
				sampleVertexs.clear();
			}
			this.invalidate();
		}
		return true;
	}
}

 

package com.wbhuang.myninjia;

import android.app.Activity;
import android.os.Bundle;


public class NinjiaActivity extends Activity {
    /** Called when the activity is first created. */

    @Override
    
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new ShadeView(this));
    }
    
}

 

posted @ 2013-08-21 18:04  彬麦崽  阅读(740)  评论(0编辑  收藏  举报