public class AccelerometerPlayActivity extends Activity {    private SimulationView mSimulationView; //游戏主显示View    private SensorManager mSensorManager; //感应器管理类    private PowerManager mPowerManager; //电源控制,比如防锁屏    private WindowManager mWindowManager;     private Display mDisplay;     private WakeLock mWakeLock;     @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);         mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); // 实例化感应器管理类        mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);        mDisplay = mWindowManager.getDefaultDisplay(); //为了获取屏幕的DPI级别        mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass()                .getName()); //处理屏幕防止锁屏        mSimulationView = new SimulationView(this);        setContentView(mSimulationView); //设置游戏View    }    @Override    protected void onResume() {        super.onResume();         mWakeLock.acquire();  //恢复时解除锁屏        mSimulationView.startSimulation();    }    @Override    protected void onPause() {        super.onPause();        mSimulationView.stopSimulation(); //Activity切出去时停止画面更新        mWakeLock.release();    }    class SimulationView extends View implements SensorEventListener {        private static final float sBallDiameter = 0.004f; //设置小球直径        private static final float sBallDiameter2 = sBallDiameter * sBallDiameter;        private static final float sFriction = 0.1f; //摩擦系数        private Sensor mAccelerometer;        private long mLastT;        private float mLastDeltaT;        private float mXDpi;        private float mYDpi;        private float mMetersToPixelsX;        private float mMetersToPixelsY;        private Bitmap mBitmap; //小球素材        private Bitmap mWood; //背景使用木头        private float mXOrigin;        private float mYOrigin;        private float mSensorX;        private float mSensorY;        private long mSensorTimeStamp;        private long mCpuTimeStamp;        private float mHorizontalBound;        private float mVerticalBound;        private final ParticleSystem mParticleSystem = new ParticleSystem();        class Particle {            private float mPosX;            private float mPosY;            private float mAccelX;            private float mAccelY;            private float mLastPosX;            private float mLastPosY;            private float mOneMinusFriction;            Particle() {                final float r = ((float) Math.random() - 0.5f) * 0.2f;                mOneMinusFriction = 1.0f - sFriction + r;            }            public void computePhysics(float sx, float sy, float dT, float dTC) {                final float m = 1000.0f; // mass of our virtual object                final float gx = -sx * m;                final float gy = -sy * m;               final float invm = 1.0f / m;                final float ax = gx * invm;                final float ay = gy * invm;                final float dTdT = dT * dT;                final float x = mPosX + mOneMinusFriction * dTC * (mPosX - mLastPosX) + mAccelX                        * dTdT;                final float y = mPosY + mOneMinusFriction * dTC * (mPosY - mLastPosY) + mAccelY                        * dTdT;                mLastPosX = mPosX;                mLastPosY = mPosY;                mPosX = x;                mPosY = y;                mAccelX = ax;                mAccelY = ay;            }            public void resolveCollisionWithBounds() {                final float xmax = mHorizontalBound;                final float ymax = mVerticalBound;                final float x = mPosX;                final float y = mPosY;                if (x > xmax) {                    mPosX = xmax;                } else if (x < -xmax) {                    mPosX = -xmax;                }                if (y > ymax) {                    mPosY = ymax;                } else if (y < -ymax) {                    mPosY = -ymax;                }            }        }        class ParticleSystem { //收集取样感应器数据来绘制小球位置            static final int NUM_PARTICLES = 15;            private Particle mBalls[] = new Particle[NUM_PARTICLES];            ParticleSystem() {                    for (int i = 0; i < mBalls.length; i++) {                    mBalls[i] = new Particle();                }            }            private void updatePositions(float sx, float sy, long timestamp) {                final long t = timestamp;                if (mLastT != 0) {                    final float dT = (float) (t - mLastT) * (1.0f / 1000000000.0f);                    if (mLastDeltaT != 0) {                        final float dTC = dT / mLastDeltaT;                        final int count = mBalls.length;                        for (int i = 0; i < count; i++) {                            Particle ball = mBalls[i];                            ball.computePhysics(sx, sy, dT, dTC);                        }                    }                    mLastDeltaT = dT;                }                mLastT = t;            }            public void update(float sx, float sy, long now) {                updatePositions(sx, sy, now);                  final int NUM_MAX_ITERATIONS = 10;                boolean more = true;                final int count = mBalls.length;                for (int k = 0; k < NUM_MAX_ITERATIONS && more; k++) {                    more = false;                    for (int i = 0; i < count; i++) {                        Particle curr = mBalls[i];                        for (int j = i + 1; j < count; j++) {                            Particle ball = mBalls[j];                            float dx = ball.mPosX - curr.mPosX;                            float dy = ball.mPosY - curr.mPosY;                            float dd = dx * dx + dy * dy;                            // Check for collisions                            if (dd <= sBallDiameter2) {                                dx += ((float) Math.random() - 0.5f) * 0.0001f;                                dy += ((float) Math.random() - 0.5f) * 0.0001f;                                dd = dx * dx + dy * dy;                                // simulate the spring                                final float d = (float) Math.sqrt(dd);                                final float c = (0.5f * (sBallDiameter - d)) / d;                                curr.mPosX -= dx * c;                                curr.mPosY -= dy * c;                                ball.mPosX += dx * c;                                ball.mPosY += dy * c;                                more = true;                            }                        }                        curr.resolveCollisionWithBounds();                    }                }            }            public int getParticleCount() {                return mBalls.length;            }            public float getPosX(int i) {                return mBalls[i].mPosX;            }            public float getPosY(int i) {                return mBalls[i].mPosY;            }        }        public void startSimulation() {            mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_UI);        }        public void stopSimulation() { //暂停时主要是停掉感应器            mSensorManager.unregisterListener(this);        }        public SimulationView(Context context) {            super(context);            mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); //实例化加速感应器            DisplayMetrics metrics = new DisplayMetrics();            getWindowManager().getDefaultDisplay().getMetrics(metrics); //分辨率获取            mXDpi = metrics.xdpi;            mYDpi = metrics.ydpi;            mMetersToPixelsX = mXDpi / 0.0254f;             mMetersToPixelsY = mYDpi / 0.0254f;            Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);            final int dstWidth = (int) (sBallDiameter * mMetersToPixelsX + 0.5f);            final int dstHeight = (int) (sBallDiameter * mMetersToPixelsY + 0.5f);            mBitmap = Bitmap.createScaledBitmap(ball, dstWidth, dstHeight, true); //根据屏幕分辨率来设置素材的显示缩放比例            Options opts = new Options();            opts.inDither = true;            opts.inPreferredConfig = Bitmap.Config.RGB_565;            mWood = BitmapFactory.decodeResource(getResources(), R.drawable.wood, opts);        }        @Override        protected void onSizeChanged(int w, int h, int oldw, int oldh) { //当View有变化时,Android123提示比如说横竖屏切换            mXOrigin = (w - mBitmap.getWidth()) * 0.5f;            mYOrigin = (h - mBitmap.getHeight()) * 0.5f;            mHorizontalBound = ((w / mMetersToPixelsX - sBallDiameter) * 0.5f);            mVerticalBound = ((h / mMetersToPixelsY - sBallDiameter) * 0.5f);        }        @Override        public void onSensorChanged(SensorEvent event) { //感应器数据有变化时            if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)                return;            switch (mDisplay.getRotation()) {                case Surface.ROTATION_0:                    mSensorX = event.values[0];                    mSensorY = event.values[1];                    break;                case Surface.ROTATION_90:                    mSensorX = -event.values[1];                    mSensorY = event.values[0];                    break;                case Surface.ROTATION_180:                    mSensorX = -event.values[0];                    mSensorY = -event.values[1];                    break;                case Surface.ROTATION_270:                    mSensorX = event.values[1];                    mSensorY = -event.values[0];                    break;            }            mSensorTimeStamp = event.timestamp;            mCpuTimeStamp = System.nanoTime();        }        @Override        protected void onDraw(Canvas canvas) { //主要的小球绘制            canvas.drawBitmap(mWood, 0, 0, null); //先画出背景            final ParticleSystem particleSystem = mParticleSystem;            final long now = mSensorTimeStamp + (System.nanoTime() - mCpuTimeStamp);            final float sx = mSensorX;            final float sy = mSensorY;            particleSystem.update(sx, sy, now);            final float xc = mXOrigin;            final float yc = mYOrigin;            final float xs = mMetersToPixelsX;            final float ys = mMetersToPixelsY;            final Bitmap bitmap = mBitmap;            final int count = particleSystem.getParticleCount();            for (int i = 0; i < count; i++) {                final float x = xc + particleSystem.getPosX(i) * xs;                final float y = yc - particleSystem.getPosY(i) * ys;                canvas.drawBitmap(bitmap, x, y, null);            }            invalidate();        }        @Override        public void onAccuracyChanged(Sensor sensor, int accuracy) {        }    }}

整个例子可以在Android 2.3 SDK的Samples文件夹下找到,这个小铁球的例子可以帮助我们改造为平衡球游戏。

更多相关文章

  1. Android拖动改变小球位置
  2. 关于Android重力感应器的频率的分析
  3. android画图——Path()的使用
  4. 【Android笔记 七】Android(安卓)Sensor感应器介绍(三)获取用户移
  5. android 获取手机屏幕分辨率和setRequestedOrientation设置屏幕
  6. 学习笔记|Android中的setRequestorientation
  7. 初学Android,开发自定义的View(四)
  8. 第七天android:弹球1
  9. Android中传感器的一些功能

随机推荐

  1. 异步加载图片
  2. 【环境配置】配置ndk
  3. Android中 网络框架Volley的用法
  4. Android权限问题:Permission is only gra
  5. Android跨进程通信IPC之19——AIDL
  6. android 垂直 SeekBar 源代码(VerticalSe
  7. Android(安卓)DownloadManager 的使用
  8. Android(安卓)不得不知Tag的妙用
  9. Android之Intent(一)
  10. Android中捕捉menu按键点击事件的方法