android 如何使用surfaceview绘制类似游戏手柄的摇杆?
来源:互联网 发布:手机淘宝退运费险流程 编辑:程序博客网 时间:2024/05/01 08:24
网上找到比较少关于此类的文章,估计是高手都比较忙,没空分享这样的东西。今天乘有空发表一下。
具体分3步:
1.创建一个holder,可以理解为我们美术生常用的画板架。
surfaceview的原理是在屏幕上不停的画图,通过不断地刷新每次画好的图,形成流畅的动画或其他图像,刷新频率极高,如同早期迪士尼动画一样。
2.Run the canvas! : canvas就是画布,不难理解了吧,我们往canvas 绘制circle ,绘制image,绘制矩形都在这里进行。注意会之前要将画布lock在holder上,画完后再unlock
3.定义onTouch事件,就是定义手指触碰摇杆时应该发生什么行为。重点语句在
mRockerPosition.set((int)event.getX(), (int)event.getY()),mRockerPosition随手指的点坐标改变而改变,令canvas的每次绘制摇杆的位置都有所不同,这就形成了手柄效果。
import com.wincent.wavegenerator.R;import com.wincent.wavegenerator.activity.WaveGeneratorActivity;import com.wincent.wavegenerator.test.Rudder2.RudderListener;import com.wincent.wavegenerator.tools.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.graphics.Rect;import android.graphics.RectF;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager; import android.util.AttributeSet;import android.util.Log; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView;import android.view.SurfaceHolder.Callback;import android.view.View;public class RudderSample extends SurfaceView implements Runnable,Callback{ private float sensorX;private float sensorY;private SurfaceHolder mHolder;private boolean isStop = false;private Thread mThread;private Paint mPaint;public Point mRockerPosition; //摇杆位置public static boolean sensorOn=false;public int mWheelRadius = 60;//摇杆活动范围半径,难道这个是DP单位?原来是60public Point mCtrlPoint;// = new Point(mRudderRadius+mWheelRadius,mRudderRadius+mWheelRadius);//摇杆起始位置public RudderListener listener = null; //事件回调接口public int d;public int orientation=1;private float sensorXinCirle;private float sensorYinCirle;public SensorManager sensorMgr;private Sensor sensor;public SensorEventListener lsn;private Bitmap rudder;private boolean isDestroyed=false;private int testRadius;private Paint paintBlack;public Point testPoint;private Point centerPoint=new Point(80,80);public static final int ACTION_RUDDER = 1 , ACTION_ATTACK = 2; // 1:摇杆事件 2:按钮事件(未实现)public RudderSample(Context context) {super(context);//mCtrlPoint.set(WaveGeneratorActivity.rudderCenter.x,WaveGeneratorActivity.rudderCenter.y); }public RudderSample(Context context, AttributeSet as) {super(context, as);this.setKeepScreenOn(true);mHolder = getHolder();mHolder.addCallback(this); mThread = new Thread(this);mPaint = new Paint();mPaint.setColor(Color.GREEN);//mPaint.setAntiAlias(true);//抗锯齿mPaint.setStyle(Paint.Style.STROKE);//测试代码paintBlack=new Paint();paintBlack.setColor(Color.RED);paintBlack.setAntiAlias(true);mRockerPosition=new Point();testPoint=new Point();mRockerPosition.set(centerPoint.x,centerPoint.y);mCtrlPoint=new Point();mCtrlPoint.set(centerPoint.x,centerPoint.y);//mCtrlPoint.set();setFocusable(true);setFocusableInTouchMode(true);setZOrderOnTop(true);mHolder.setFormat(PixelFormat.TRANSPARENT);//设置背景透明 rudder = BitmapFactory.decodeResource(getResources(),R.drawable.rudder); } //设置回调接口public void setRudderListener(RudderListener rockerListener) {listener = rockerListener;}@Overridepublic void run() {Canvas canvas = null;while(!isStop) {try {//----11.30修改,加入代码,测试那个圆到底有多大canvas = mHolder.lockCanvas();canvas.drawColor(Color.TRANSPARENT,Mode.CLEAR);//清除屏幕canvas.drawCircle(mCtrlPoint.x, mCtrlPoint.y, testRadius, mPaint); //摇杆可活动范围圆环drawImage(canvas, rudder, mRockerPosition.x, mRockerPosition.y,rudder.getWidth(), rudder.getHeight(), 0, 0);//canvas.drawRect(testPoint.x, testPoint.y, testPoint.x+40, testPoint.y+40, paintBlack);} catch (Exception e) { e.printStackTrace(); } finally { if(canvas != null) { mHolder.unlockCanvasAndPost(canvas); }} try { Thread.sleep(30);} catch (InterruptedException e) { e.printStackTrace();}}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}@Overridepublic void surfaceCreated(SurfaceHolder holder) {isStop = false;mThread=new Thread(this);mThread.start(); }@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {isStop = true;mThread.interrupt();}@Overridepublic boolean onTouchEvent(MotionEvent event) { if(!sensorOn){//----int len = MathUtils.getLength(mCtrlPoint.x, mCtrlPoint.y, event.getX(), event.getY());int len = MathUtils.getLength(mCtrlPoint.x, mCtrlPoint.y, event.getX(), event.getY());if(event.getAction() == MotionEvent.ACTION_DOWN) {//如果屏幕接触点不在摇杆挥动范围内,则不处理if(len >mWheelRadius) { return true;}}if(event.getAction() == MotionEvent.ACTION_MOVE){if(len <= mWheelRadius) { //如果手指在摇杆活动范围内,则摇杆处于手指触摸位置 mRockerPosition.set((int)event.getX(), (int)event.getY());//Point d=len;}else{ //设置摇杆位置,使其处于手指触摸方向的 摇杆活动范围边缘 mRockerPosition = MathUtils.getBorderPoint(mCtrlPoint, new Point((int)event.getX(), (int)event.getY()), mWheelRadius); d=60; }if(listener != null) {Log.v("len",event.getX()+","+event.getY());float radian = MathUtils.getRadian(mCtrlPoint, new Point((int)event.getX(), (int)event.getY()));double radianUnsigned=(float) MathUtils.angUnsigned;listener.onSteeringWheelChanged(ACTION_RUDDER,radianUnsigned,d);Log.v("sensor",d+","+radianUnsigned);}}//如果手指离开屏幕,则摇杆返回初始位置if(event.getAction() == MotionEvent.ACTION_UP) {mRockerPosition = new Point(mCtrlPoint);d=0;} return true;}else{if(lsn!=null){float radian = MathUtils.getRadian(mCtrlPoint, new Point((int)sensorXinCirle, (int)sensorYinCirle));radianUnsigned=(float) MathUtils.angUnsigned;listener.onSteeringWheelChanged(ACTION_RUDDER,radianUnsigned,d);Log.v("sensor",d+","+radianUnsigned);}} 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);}}int MAX_TOUCHPOINTS=3;public float radianUnsigned;public boolean center=false;//回调接口public interface RudderListener {void onSteeringWheelChanged(int action,double radianUnsigned, int d);}/** * 绘制图片 * * @paramx 屏幕上的x坐标 * @paramy 屏幕上的y坐标 * @paramw 要绘制的图片的宽度 * @paramh 要绘制的图片的高度 * @parambx图片上的x坐标 * @paramby图片上的y坐标 * * @returnnull */public void drawImage(Canvas canvas, Bitmap blt, int x, int y, int w, int h, int bx, int by){Rect src = new Rect();// 图片Rect dst = new Rect();// 屏幕src.left = bx;src.top = by;src.right = bx + w;src.bottom = by + h;dst.left = x-(w/2);dst.top = y-(h/2);dst.right = x + (w/2);dst.bottom = y + (h/2);canvas.drawBitmap(blt, src, dst, null);src = null;dst = null;} public void enableSensor(){//----周日删除 sensorOn=true;sensorMgr.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME);}public void disableSensor(){//----周日删除sensorOn=false;sensorMgr.unregisterListener(lsn, sensor);mRockerPosition=new Point(mCtrlPoint);}}下一集,我们专门讲解如何实现多点触碰进行摇杆控制
- android 如何使用surfaceview绘制类似游戏手柄的摇杆?
- android虚拟手柄摇杆的实现
- 用SurfaceView实现Android游戏摇杆
- 用SurfaceView实现Android游戏摇杆
- 游戏杆,摇杆,joystick,游戏手柄的一个.NET库
- android 学习之路(surfaceView) --- 游戏手柄设计
- 一个游戏设备的Win32库,游戏杆,摇杆,手柄操作
- 今天把之前开发的捕鱼游戏加上摇杆手柄的支持,在家拿摇杆玩捕鱼,一样开心!
- android模拟摇杆绘制
- android 虚拟摇杆绘制
- android 虚拟摇杆绘制
- Android SurfaceView的绘制详解
- 手机游戏绘制触屏虚拟摇杆的几何算法
- Android手机游戏摇杆
- android游戏手柄问题
- Android-使用SurfaceView多线程绘制动画
- 游戏中SurfaceView的使用
- 手机游戏的摇杆
- 经典PVST+到Rapid-PVST+迁移配置示例
- C# 深度解说值传参和引用传参的原理
- PHP框架收集
- PHP Warning: date() [function.date]: It is not safe to rely on the system's timezone settings.
- 安装phpmyadmin的注意事项
- android 如何使用surfaceview绘制类似游戏手柄的摇杆?
- windows下命令行编译c/c++源码
- 探索Linux超线程感知的调度算法
- arraysize和consistent get的关系
- 蒙牛果然“猛”!
- C#抓取ajax异步数据
- 学习effective java-1创建和销毁对象之静态工厂方法
- 2011年度国内10佳iOS应用
- 要查数据表中第30到40条记录,有字段id,但是id并不连续。如何写sql语句?