android 虚拟摇杆图片版

     在之前A single virtual joystick development使用的圆盘和摇杆都是使用颜色来实现的,但是在实际的开发过程中,这并不美观,所有在这使用图片替换之前使用颜色的圆盘和摇杆,两者之间的区别在于,使用颜色绘制使用的是中心点作为坐标,而使用图片则使用的是左上角作为坐标,所以这里需要进行转换,同时注意的就是图片的宽度问题,里面计算的都是使用的像素,而你一开始将图片转化为bitmap的时候并不是你期望的尺寸,这里也需要转换,最后一点就是摇杆图片移动的问题,这里有两个方案,一个是改变坐标(要实现这种方法则可以使用组件显示图片,然后移动组件),第二种方法就是我现在使用的canvas绘制每次都是先清空颜色然后重新绘制的方法。

      实现圆盘和摇杆功能的类---AppSingleRocker.java:

package com.seuic.singlerocker;

import com.seuic.util.MathUtils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;

public class AppSingleRocker extends SurfaceView implements Callback{

	private SurfaceHolder mHolder;
	private Paint mPaint;
	public Point mRockerPosition; // 摇杆位置
	private Point mCtrlPoint = new Point(80, 80);// 摇杆起始位置
	//private int mRudderRadius = 20;// 摇杆半径
	private int mWheelRadius = 60;// 摇杆活动范围半径
	int isHide = 0;
	private SingleRudderListener listener = null; //事件回调接口
	Bitmap bitmap,bitmap2;
	public static final int ACTION_RUDDER = 1, ACTION_ATTACK_DEVICEMOVE = 2, ACTION_STOP = 3,  ACTION_ATTACK_CAMERAMOVE = 4;
	public AppSingleRocker(Context context) {
		super(context);
		this.setKeepScreenOn(true);
        mHolder = getHolder();
        mHolder.addCallback(this);
        mPaint = new Paint();
        mPaint.setColor(Color.GREEN);
        mPaint.setAntiAlias(true);//抗锯齿
        mRockerPosition = new Point(mCtrlPoint);
        setFocusable(true);
        setFocusableInTouchMode(true);
        setZOrderOnTop(true);
        mHolder.setFormat(PixelFormat.TRANSPARENT);//设置背景透明                                                                                   

        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.j4);
        bitmap = Bitmap.createScaledBitmap(bitmap, 120, 120, false);
        bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.j5);
        bitmap2 = Bitmap.createScaledBitmap(bitmap2, 40, 40, false);

}

public AppSingleRocker(Context context, AttributeSet attribute)

{super(context, attribute);

this.setKeepScreenOn(true);

mHolder = getHolder();

mHolder.addCallback(this);

mPaint = new Paint();

mPaint.setColor(Color.GREEN);

mPaint.setAntiAlias(true);//抗锯齿

mRockerPosition = new Point(mCtrlPoint);

setFocusable(true);

setFocusableInTouchMode(true);

setZOrderOnTop(true);

mHolder.setFormat(PixelFormat.TRANSPARENT);//设置背景透明  

bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.j4);       

bitmap = Bitmap.createScaledBitmap(bitmap, 120, 120, false);       

bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.j5);       

bitmap2 = Bitmap.createScaledBitmap(bitmap2, 40, 40, false);

}

//回调接口

public interface SingleRudderListener {

void onSteeringWheelChanged(int action,int angle);

}

//设置回调接口

public void setSingleRudderListener(SingleRudderListener rockerListener) {

listener = rockerListener;

}

int len;

@Override

public boolean onTouchEvent(MotionEvent event) {

try {

if (isHide == 0) {

switch (event.getAction())

{

case MotionEvent.ACTION_DOWN:

len = MathUtils.getLength(mCtrlPoint.x, mCtrlPoint.y, event.getX(), event.getY()); //如果屏幕接触点不在摇杆挥动范围内,则不处理

if(len >mWheelRadius) {

return true;

}

break;

case MotionEvent.ACTION_MOVE:

len = MathUtils.getLength(mCtrlPoint.x, mCtrlPoint.y, event.getX(), event.getY());

if(len <= mWheelRadius) {

//如果手指在摇杆活动范围内,则摇杆处于手指触摸位置

mRockerPosition.set((int)event.getX(), (int)event.getY());

}else{

//设置摇杆位置,使其处于手指触摸方向的 摇杆活动范围边缘

mRockerPosition = MathUtils.getBorderPoint(mCtrlPoint, new Point((int)event.getX(), (int)event.getY()), mWheelRadius);

}

if(listener != null) {

float radian = MathUtils.getRadian(mCtrlPoint, new Point((int)event.getX(), (int)event.getY()));

listener.onSteeringWheelChanged(ACTION_RUDDER, getAngleCouvert(radian));

}

break;

case MotionEvent.ACTION_UP:

mRockerPosition = new Point(mCtrlPoint);

listener.onSteeringWheelChanged(ACTION_STOP, 0);

break;

}

Canvas_OK();

Thread.sleep(60);

}else {

Thread.sleep(200);

}

} catch (Exception e) {

}

return true;

}

//获取摇杆偏移角度 0-360°

private int getAngleCouvert(float radian) {

int tmp = (int)Math.round(radian/Math.PI*180);

if(tmp < 0) {

return -tmp;

}else{

return 180 + (180 - tmp);

}

}

public void surfaceCreated(SurfaceHolder holder) {

Canvas_OK();

}

public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {

}

public void surfaceDestroyed(SurfaceHolder holder) {

}

// 设置是否隐藏

public void Hided(int opt){

isHide = opt;

Canvas_OK();

}

//绘制图像public void Canvas_OK(){

Canvas canvas = null;

try {

canvas = mHolder.lockCanvas();

canvas.drawColor(Color.TRANSPARENT,Mode.CLEAR);//清除屏幕

canvas.drawBitmap(bitmap, mCtrlPoint.x - 60, mCtrlPoint.y-60, mPaint);

//这里的60px是最外围的图片的半径 canvas.drawBitmap(bitmap2, mRockerPosition.x - 20, mRockerPosition.y-20, mPaint);

//这里的20px是最里面的图片的半径

} catch (Exception e) {

e.printStackTrace();

} finally {

if(canvas != null) {

mHolder.unlockCanvasAndPost(canvas);

} }}}


主类,调用圆盘的类----SingleRocker.java

package com.seuic.singlerocker;

import com.seuic.singlerocker.AppSingleRocker.SingleRudderListener;

import android.os.Bundle;
import android.util.Log;
import android.widget.RelativeLayout;
import android.app.Activity;

public class SingleRocker extends Activity {
	
	RelativeLayout Parent;
	AppSingleRocker appSingleRocker;
	public static final String Main = "SingleRocker";
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Parent = new RelativeLayout(this);
		RelativeLayout.LayoutParams RockerCanvasParams = new RelativeLayout.LayoutParams(160,160);
		RockerCanvasParams.addRule(RelativeLayout.CENTER_VERTICAL);
		RockerCanvasParams.leftMargin = 120;
		appSingleRocker = new AppSingleRocker(this);
		Parent.addView(appSingleRocker,RockerCanvasParams);
		setContentView(Parent);
		appSingleRocker.setSingleRudderListener(new SingleRudderListener() {
			@Override
			public void onSteeringWheelChanged(int action, int angle) {
				Log.e(Main, angle+"");
			}
		});
	}

}


实现的图片如下:

android 虚拟摇杆图片版_第1张图片

android 虚拟摇杆图片版_第2张图片

源码连接地址如下:


 http://download.csdn.net/download/jwzhangjie/5291058

注:

源代码里面需要修改

在AppSingleRocker.java中将

bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.j4);

bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.j5); 

替换为

bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.j4); 

bitmap = Bitmap.createScaledBitmap(bitmap, 120, 120, false); 

bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.j5); 

bitmap2 = Bitmap.createScaledBitmap(bitmap2, 40, 40, false); 


不然适应性不好,因为我是在华硕大平板上调试的,上面的代码是可以的,但是如果到了其他的机器就不好了,所以使用下面的代码通用性。

 


   

你可能感兴趣的:(android 虚拟摇杆图片版)