Android新手上路——自定义SurfaceView,重力感应小球
来源:互联网 发布:手机客户端制作软件 编辑:程序博客网 时间:2024/05/07 19:20
如有错误,还请指正
- SurfaceView的使用
- 加速度传感器的使用
- 重力小球View的代码
package com.example.doge_gravityjumpingaty.view;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;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.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;/** * @author fhbianling--- A little learning is a dangerous thing. * @mail fhbianling@163.com * @time 2016-6-26下午4:04:32 */public class GravityJumpingView extends SurfaceView implements Runnable, Callback { /** * SurfaceView可以在非UI线程中绘制界面,因此在重绘频繁的情况下,可以考虑使用SurfaceView * 它的回调中两个主要的方法: * 通过getHolder().lockCanvas()获得一个Canvas对象,在这个Canvas上作画, * 然后getHolder().unlockCanvasAndPost(Canvas canvas)提交画布,并显示。 注意这三步操作要加同步锁 **/ private Paint mPaint; private Sensor sensorG; private SensorManager manager; private int viewWidth; private int viewHeight; private int radiusBall; private boolean isRunning; private int centerXmin, centerXmax, centerYmin, centerYmax; private int centerX, centerY; private float aX, aY; private float vX, vY; private Canvas mCanvas; private SurfaceHolder mHolder; /** * 传感器的监听器 */ private SensorEventListener mListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { /** 将当前加速度赋值给全局变量用以在线程中更新圆球圆心位置 **/ /** 对于加速度传感器,其event.values[]的0,1,2下标的三个值分别对应当前手机x,y,z方向的加速度 **/ /** 这个坐标系,以手机屏幕左至右为x方向正方向,下至上为y方向正方向,垂直屏幕指向屏幕上方为z正方向 **/ /** 和2d时的相关x,y方向(如onTouchEvent()中的event.getY())不同 **/ aX = event.values[0]; aY = event.values[1]; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { /** 这个回调方法在传感器精度改变时被触发,在这个demo中并不需要做任何操作 **/ } }; /** * 初始化传感器和画笔 * * @param context */ private void init(Context context) { mPaint = new Paint(); mPaint.setAntiAlias(true); // 通过context获得系统服务-->传感器管理器 manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); // 通过传感器管理器获得加速度传感器,获取其他传感器的方法只需传入不同的Sensor.Type...常量值即可 // 不同的手机拥有的传感器不一定一样,不常用的传感器,一般的手机生产厂商不会提供 // 通过SensorManager对象的 // .getSensorList(Sensor.TYPE_ALL)方法可以返回一个手机拥有的传感器的List<Sensor>集合 sensorG = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // 为SurfaceView的SurfaceHolder添加回调接口,这个接口的三个方法分别在Surface创建,销毁和改变时触发 // 一个surface可以理解为对应的SurfaceView的一个可见区域,并且它是直接对应到内存中的,因此它有自己的生命周期 // 分别就对应了surfaceCreate,surfaceChange,surfaceDestroy三个方法 mHolder = this.getHolder(); mHolder.addCallback(this); } public GravityJumpingView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public GravityJumpingView(Context context) { super(context); init(context); } public GravityJumpingView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } /** * 通过使这个View本身实现Runnable接口来绘制界面, 并通过Runnable的线程休眠达到控制每秒帧数的效果, * 因为传感器的数据变化较快,控制每秒重绘次数避免绘制太多次。 */ @Override public void run() { // 注册监听器的第三个参数用于控制传感器获取数值的频率 manager.registerListener(mListener, sensorG, SensorManager.SENSOR_DELAY_NORMAL); Log.d("Listener", "register"); while (isRunning) { vX -= aX; // 这里的反向是由于坐标系转换 vY += aY; centerX += vX; centerY += vY; // V1=V0+a*t;sX1=sX0+vX*t;物理公式的简单运用 // 以下两个if...else...结构用于进行边界检测 if (centerX <= centerXmin) { centerX = centerXmin; // 使反向后的vX的数值变为之前的4/5是为了模拟碰撞过程中弹性形变造成的动能损失,vY同 vX = -vX * 4 / 5; } else if (centerX >= centerXmax) { centerX = centerXmax; vX = -vX * 4 / 5; } if (centerY <= centerYmin) { centerY = centerYmin; vY = -vY * 4 / 5; } else if (centerY >= centerYmax) { centerY = centerYmax; vY = -vY * 4 / 5; } try { // 在数据刷新后的绘画过程 synchronized (mHolder) { // mCanvas=mHolder.lockCanvas(dirty)方法,dirty是一个Rect类的实例, // 通过这个方法可以只在dirty这个矩形的区域内更新画面,以进一步优化绘制的内存消耗, //在这里使用的.lockCanvas()方法会绘制整个Canvas区域 mCanvas = mHolder.lockCanvas(); draw(); mHolder.unlockCanvasAndPost(mCanvas); } // 使线程睡眠50ms达到近似每秒20帧的帧数 Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } } // 在循环结束后注销传感器 if (manager != null && mListener != null) { manager.unregisterListener(mListener); Log.d("Listener", "unregister"); } } /** * 绘制数据更新后的小球 */ private void draw() { if (mPaint == null || mCanvas == null) { return; } // 画白色背景 mPaint.setStyle(Style.FILL_AND_STROKE); mPaint.setColor(Color.WHITE); mCanvas.drawRect(0, 0, viewWidth, viewHeight, mPaint); // 画移动范围边框 mPaint.setColor(Color.BLACK); mPaint.setStyle(Style.STROKE); mCanvas.drawRect(0, 0, viewWidth, viewHeight, mPaint); // 画小球 mPaint.setStyle(Style.FILL_AND_STROKE); mCanvas.drawCircle(centerX, centerY, radiusBall, mPaint); } /** * 在surface创建时注册监听,初始化数据,并启动绘制线程, 这个方法在onAttachedToWindow()后被调用 */ @Override public void surfaceCreated(SurfaceHolder holder) { start(); Log.d("surfaceCreated", "1"); } /** * start方法用于初始化数据,并启动绘制线程 */ private void start() { isRunning = true; viewWidth = getWidth(); viewHeight = getHeight(); radiusBall = Math.min(viewWidth, viewHeight) / 20; centerXmin = radiusBall; centerXmax = viewWidth - radiusBall; centerYmin = radiusBall; centerYmax = viewHeight - radiusBall; centerX = viewWidth / 2; centerY = viewHeight / 2; // centerX,centerY的Min,Max分别对应圆心的最小范围和最大范围 // centerX,centerY代表绘制圆形的实时圆心位置 new Thread(this).start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d("surfaceChanged", "2"); } /** * 在surfaceDestroyed()方法中停止线程,注销传感器注册在run()中执行, * 这个方法会在onDetachedToWindow()后被调用 */ @Override public void surfaceDestroyed(SurfaceHolder holder) { isRunning = false; Log.d("surfaceDestroyed", "3"); }}
布局参数和Acitivity很简单就不贴了。
0 0
- Android新手上路——自定义SurfaceView,重力感应小球
- Unity3D学习笔记——Android重力感应控制小球
- Unity3D学习笔记——Android重力感应控制小球
- android 重力感应小球 Demo
- Android 小球重力感应实现
- Android 小球重力感应实现
- android 重力感应小球 Demo
- android小游戏模版—重力感应
- Android游戏开发之小球重力感应实现
- Android游戏开发之小球重力感应实现
- Android游戏开发之小球重力感应实现
- Android游戏开发之小球重力感应实现
- 17、Android之SurfaceView实例自定义SurfaceView的应用——小球跟着手指移动
- 【Android】弹跳的小球——SurfaceView
- Unity3D之平面小球重力感应详解
- 【cocos2d-x】重力感应----移动小球
- HTML5重力感应小球冲撞动画实现
- 通过重力感应小球移动位置
- TOJ 4153 I like graph
- extjs3里面的获取不到store内数值,采用store.on('load', function() {});不执行
- 大内高手—栈/堆
- echarts2.0 时间轴搭配力导向图使用+时间轴数据覆盖问题的解决
- iOS深入学习(Block全面分析)
- Android新手上路——自定义SurfaceView,重力感应小球
- Android 软键盘盖住输入框或者布局的解决办法
- 用C语言实现常见的三种中文内码转换
- js(十)——dom模型
- Java面向对象思想总结
- labview软件介绍
- java中字符串的的替换replace和replaceAll的区别
- 一个非常不错的串口程序
- TF-IDF来源及理论推导 熵推导出