1.紧接第一篇,创建一些类
Vec.java (用来表示速度的)
View Code
public class Vec { public Float _x, _y; Vec(){ _x = _y = 0.f; } Vec(float x, float y){ _x = x; _y = y; } float getAngle(){ return (float)Math.atan2(_x, _y); } //坐标系内任意一点到原点的距离 float getLength(){ return (float)Math.sqrt(_x *_x + _y * _y); } }
Circle.java (表示玩家各项参数属性的)
View Code
public class Circle { public float _x, _y, _r; Circle(){ _x = _y = _r = 0; } //座标x,y, 半径r Circle(float x, float y, float r){ _x = x; _y = y; _r = r; } }
Player.java (表示玩家)
View Code
public class Player extends Task { private final static float SIZE = 20; //半径 private Circle _cir = null; //表示自身的圆 private Paint _paint = new Paint(); //画笔 private Vec _vec = new Vec(); //速度 public Player(){ _cir = new Circle( 240, 0, SIZE );//在(240,0)生成玩家 _paint.setColor(Color.BLUE); //颜色 _paint.setAntiAlias(true); //抗锯齿 _vec._y = 2; //设置初始的方向 } @Override public boolean onUpdate(){ _cir._x += _vec._x; //更新玩家的移动 _cir._y += _vec._y; return true; } @Override public void onDraw( Canvas c ){ c.drawCircle(_cir._x, _cir._y, _cir._r, _paint); } }
AcSensor.java (重力感应器,写法网上一搜一大堆,要注意在activity暂停时注销感应器,不然会多次注册出错)
View Code
public class AcSensor implements SensorEventListener { private SensorManager _sensorManager = null; private float _x, _y, _z; public void onCreate(Context c) { // 获取系统sensorManager _sensorManager = (SensorManager) c .getSystemService(Context.SENSOR_SERVICE); onResume(); } public void onResume() { // 获取sensor Sensor sensor = _sensorManager .getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // 注册sensor _sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST); } public void onPause() { if (_sensorManager == null) { return; } _sensorManager.unregisterListener(this); } //当感应器数值改变时 @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { _x = event.values[SensorManager.DATA_X]; _y = event.values[SensorManager.DATA_Y]; _z = event.values[SensorManager.DATA_Z]; } } public float getX() { return _x; } public float getY() { return _y; } public float getZ() { return _z; } // 频率改变时调用,也就是SensorManager.SENSOR_DELAY_FASTEST改变时 //这里暂时用不上 @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub } //singleton单例模式 private static AcSensor _instance = new AcSensor(); private AcSensor() { _x = _y = _z = 0; } public static AcSensor Inst() { return _instance; } }
记得把player添加到tasklist中,
在GameMgr.java中的_taskList.add( new FpsController() );前添加_taskList.add( new Player() );
让玩家与感应器连接起来,在Player.java的update方法中加入
//从传感器获取数据 float x = -AcSensor.Inst().getX(); float y = AcSensor.Inst().getY();
还记得重力感应器用了单例模式么?
IrairaBarActivity.java代码如下
View Code
public class IrairaBarActivity extends Activity implements GestureDetector.OnGestureListener { GameSurfaceView _view; @Override protected void onCreate(Bundle savedInstanceState) { // 设置全屏 getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); // 去除标题 requestWindowFeature(Window.FEATURE_NO_TITLE); // 确保屏幕不会自动关闭 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); super.onCreate(savedInstanceState); _view = new GameSurfaceView(this); setContentView(_view); // sensor的初始化 AcSensor.Inst().onCreate(this); } @Override protected void onResume() { super.onResume(); // 游戏重开时使感应器也重开 AcSensor.Inst().onResume(); } @Override protected void onPause() { super.onPause(); // 游戏暂停时感应器也暂停 AcSensor.Inst().onPause(); } }
2.为小球的移动加上惯性吧
在Vec.java加入两个方法
View Code
//限制最大速度 void setLengthCap( float maxLength ){ float len = getLength(); if( maxLength == 0 ){ return; } if( len > maxLength ){ float rate =len/maxLength; _x /= rate; _y /= rate; } } //速度变化快慢 void blend( Vec vec, float rate ){ float w = vec._x - _x; float h = vec._y - _y; _x += w*rate; _y += h*rate; }
最后的Player.java更新如下
View Code
public class Player extends Task { private final static float SIZE = 10; // 自身大小 private Circle _cir = null; // 自身 private Paint _paint = new Paint(); // 画出自己所需要的画笔 private Vec _vec = new Vec(); // 自身的移动方向 private Vec _sensorVec = new Vec(); // 传感器的速度 private final static float MAX_SPEED = 10; // 小球最大速度 public Player() { _cir = new Circle(160, 50, SIZE);// 初始化玩家位置 _paint.setColor(Color.BLUE); // 设置为蓝色 _paint.setAntiAlias(true); // 抗锯齿 _vec._y = 0.1f; // 初始化方向 } //设置小球方向速度 private void setVec() { float x = -AcSensor.Inst().getX(); //从传感器获取数据 float y = AcSensor.Inst().getY(); _sensorVec._x = x < 0 ? -x * x : x * x; //用平方可以让速度的变化幅度加大 _sensorVec._y = y < 0 ? -y * y : y * y; _sensorVec.setLengthCap(MAX_SPEED); //设置最大速度 _vec.blend(_sensorVec, 0.05f); // 速度变化的快慢 } private void Move() { // 把数据赋值给小圆球 _cir._x += _vec._x; _cir._y += _vec._y; } //取得自身圆 public final Circle getPt(){ return _cir; } @Override public boolean onUpdate() { setVec(); Move(); return true; } @Override public void onDraw(Canvas c) { c.drawCircle(_cir._x, _cir._y, _cir._r, _paint); } }
至此可以到真机上测试一下,正常的话可以得到一个重力感应球