说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Android加速感应器开发平衡球代码解析

HTML文档下载 WORD文档下载 PDF文档下载
Android加速感应器开发平衡球代码解析

作者:Android开发网


   如何使用Android的加速感应器开发一个控制铁球滚动的游戏:

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文件夹下找到,这个小铁球的例子可以帮助我们改造为平衡球游戏。

用Delphi开发分隔线组件 用Delphi设计拨动、跳线开关组件 用Delphi 设 计 拨 动、 跳 线 开 关 组 件 用Delphi实现JPEG格式图像的显示 用Delphi制作动态有声标签 运行时生成控件-Delphi资料 在DBGRID中实现COPY、PASTE功能-Delphi资料 在Delphi程序的About窗口中建立URL连接 在Delphi中利用Tbatch组件完成数据批处理 在Delphi中巧改窗体文件实现控件数组化 在Delphi中实现不同风格的SPEED和BUTTON 在Delphi中实现类似VB中的控件数组。 在RichEdit中的串查找-Delphi资料 在按钮中快速启动程序-Delphi资料 怎样读出MEMO控件的当前值-Delphi资料 怎样使用Delphi 5中的TExcelApplication操纵Excel 97/2000 怎样在TDataset中汉英混用-Delphi资料 制作可移动的窗体的MovePanel控件-Delphi资料 制作可移动的分割窗体-Delphi资料 制作用于日期时间型字段的DELPHI数据感知控件 制作主窗口显示前的版权窗口-Delphi资料 状态条插入可视控件-Delphi资料 做动态显示的控件-Delphi资料 做一个OpenGL控件-Delphi资料 Api函数列表——与打印相关-Delphi资料 Delphi 5快速创建控制面板程序 Delphi 编写Windows NT服务 Delphi 的 分 发 工 具 ─ ─InstallShield Delphi 关于系统编程中的技巧 Delphi3如何调用Excel Delphi5.0中的函数调用模式 计算机网络可以虚拟现实,但不能虚拟感情。 关于注册表的几个问题? (高分!!!) 我的vc6为什么不支持模板特化 怎么实现这个对话框的功能?谢谢 如何判断表单没有某个对象??? 怎样删除ListBox所选的内容??? 问大家一个超级难的问题,来者有分啊 请问如何把string类型转换为int类型啊? 我的msdn怎么了! C语言 在局域网中怎么才能使linux访问Internet? 我要问一个烂问题哈哈! 打印 华泰贝通,北京创智你去那家? 学习vc++,我离不开书,或者说了开书后,我什末也做不了,我该如何继续学习? 华泰贝通,北京创智你去那家? 简单问题:PB6.5中调用SQLSERVER的procedure! 打印 怎么去掉单文档视图中的菜单 华泰贝通,北京创智你去那家? 哪里有IDE技术规范的中文资料下载? 华泰贝通,北京创智你去那家? 哪里有IDE技术规范的中文资料下载? 如何把从文本登录该为Xwindow登录方式呢? 华泰贝通,北京创智你去那家? /***VC 6.0 的两个操作*/ 有关编译错误,百思不得其解!!(菜鸟那分) 怎么实现程序的换肤功能呢?? 怎样实现左连接(left outer join),右连接 这个网站制作费能值多少?? 怎样处理异质链表? 报表打开的时候缺省为最大化状态,怎么样为设计时候状态? 除了梅尔森式外,还有哪个比较好用的质数生成式?(要100位左右的) 如何在英文版的WINDOWS2k上输入中文? 为了提高大家专家分的质量,希望大家不要再散分了! 我在sun的网站上下了jdk1.4,请问怎么把JBuilder6的jdk升级到jdk1.4? 大家给推荐windows程序,sdk编程的入门好书(不是MFC的)言者有分 我在http://soft.jx163.com/上下载了JBuilder7但不知道怎样得到注册码 有没有其它免费空间(要支持ASP的) 为什么每次打开水晶报表都要求输入oricle数据库的密码和用户名,这些可以在程序里面完成吗?可以再crystalreportviewer空间里面实现翻页 请解释一下ASSERT()函数的作用 informix问题,紧急求救 求救!高手请进来 求助:build winsock 程序时出现 link 错误。 怎样能够将source safe link 像VC哪样集成到自己的应用程序? 关于用ASP+JMAIL开发一个像网易那种类似功能邮件系统的可行性!!!!大家来讨论一下!!! SQL Server7.0的ODBC驱动哪里有(不想安装客户端) 怎样将form中的值加入到数据库中 这个程序是在哪里和在什么时候执行的???? 急啊,我第一次用SQL SERVER,需要把ID号的属性定义为可自动编号,可是找不到相应的字符,可不可一帮帮我? 怎样使DLG的CLOSE(X)按钮变灰? 分子间的斥力是怎么来的?分子间的引力是不是就是万有引力?分子间存在这引力和斥力,并且随着距离的变小而变大,但那些力是怎么来的呢?分子间的引力的话是不是就是万有引力?这样的话为 金刚石和石墨是否具有相同的化学组成? 初一数学题.比较基础简单的1.在一个长方体蛋糕上切一刀,最多能把这个蛋糕切成 ( ) 块.2.过五边形的一个顶点,可以作______条对角线,这些对角线可以把这个五边形分成_______个三角形.过N边 谁能给我讲讲万有引力,分子斥力,吸力等方面的内容?我对这很感兴趣 金刚石,石墨的化学结构一个金刚石(石墨)分子由几个原子构成 把一个图形平移,旋转或画出它关于某条直线的轴对称图形,图形的大小均() 大学学的知识和高中学的有什么不同呢?大学真的想电视里说的那样轻松吗?谢谢 有一批货物,第一天运了这批货物的4分之1,第二天运的是第一天的5分之3,还剩90吨没有运,这批货物有多少吨 求美丽的平移图案,如下图,图发不出来,不好意思. 已知m自由下落,进入积雪中,已知球重m,球从空中到地面距离为h,由地面到雪里停下距离为l,利用:①单一质点的动能定理②质点系的动能定理③功能原理分别求雪对m的平均阻力. 有一批货物,第一天运了这批货物的4分之1,第二天运的是第一天的5分之3,还剩90吨没有运,这批货物有多少 平移,旋转,轴对称图形有哪些 大学电路知识求解答,部分高中的知识 (题中"/"是绝对值的符号)一、解方程1、2X+5=25-8X 2、8X-2=7X-2 3、2X+3=11-6X 4、3X-4+2X=4X-3 5、10Y+7=12-5-3Y 6、2.4X-9.8=1.4X-9 7、3Y-6=12 8、2-1-2=-2 9、23Y-4+74-18Y=4Y 10、4X-20-X=6X-54-X 11、32Y+1=21Y-3Y-13 二、解下列 静脉输液港是什么东东 还是一动初等力学题,运用到一点点大学知识.长l,质量m的刚体棒弄左端点被回转轴A连接于顶面.B点也被支撑点支撑着.棒是水平的.重力加速度g.请回答以下问题.2.1 求刚体棒的回转轴A旋转的惯 高一化学铁三角,FE,FE2,FE3之间的相互转换.最少有6个方程式.但我想要越多越好. 工业上用氢气和氧气合成氯化氢时应选择什么条件,理由是什么 已知平行四边形ABCD的周长为20,过顶点A作AE垂直DC于点E,AF垂直BC于点F,若AE=4,AF=3,则ce-cf等于 铁,硅,硫,氨水,氨,硫酸 急 为什么氯气和水反应不生成氧气或者氢气而且为什么生成次氯酸和氯化氢而不是氯化氢和氧气啊 淀粉遇到什么物质变蓝色? 氧气是不是可燃性气体 什么是静脉输液港? 什么遇淀粉变蓝 氧气是一种可燃性气体这样的说法对么? 为什么脱离火险要把脚下干草点燃 1.解二元一次方程组的主要思路是_____ 2.加减消元的主要思路是______ 1.数据收集的两种常用方法为:_____和_____ 2.全面调查是从总体中______进行调查 3.在统计中,____的全体称为总体,总体中的____称 小明跟着爸爸荡秋千.设摆绳长为3m,悬点在横梁上,小明连同底板质量共为50kg.开始时小明在爸爸的外力作用下使摆绳与竖直方向成37°角处于静止状态.某时刻爸爸放手让秋千由静止开始摆动,假 密闭式静脉输液操作方法标准是什么?请简述. 基础 的 不难的12°36′18〃=——°下列说法正确的是a、锐角的2倍是钝角b、钝角的一半是锐角(说明理由)8:00开始,到时针转了75°是结束,是几时? 为什么可燃性气体与氧气反应都得点燃才行白痴的我只能问这样的白痴问题,请见谅! 密闭式静脉输液法和静脉输液法是一个概念吗?想知道两者的关系/区别! .第一题,. 高中的物理全是力学吗?RT那为什么我看那些电子课本,必修里边全是力学? 可乐和橙子一起吃有化学反应吗? 历史上手上有十个簸箕的人物 一个滑轮上有一根绳子,下面连接着m,H和M两个重物,滑轮顶部有一个拉力让滑轮以a的加速度上升.求m,M的acceleration还有绳子两头的人tension各是多少.(补充,m,M的速度此时不一样)( 没有摩擦力) 森林与草原的区别是什么呀? 男孩子手上有十个簸箕什么意思? 如图所示,用细线悬挂的小球从A 开始摆动,经过最低点B时摆线被直尺P挡住,球继续摆动至C点.若不计空气阻力,下列说法正确的是 A.A到B过程小球的机械能增加 B.B到C过程小球的机械能减 我手指头是十个斗,有什么说法?如果男朋友是十个簸箕好吗? 利用旋转变换设计图案的步骤 利用平移变换设计图案的步骤 利用轴对称变换设计图案的步骤 在水平面上放着两个质量分别为2kg和3kg的小铁块1和2,它们之间用一根自由长度为5cm,劲度系数为100N/m的轻弹簧相连,铁块与水平面间的动摩擦因数均为0.2.铁块2受到一大小为20N的恒定水平外力F, 手指有十个簸箕的怎么解释 要准确的解释 利用平移,旋转 轴对称 中心对称 设计图案利用平移,旋转 轴对称 中心对称 的图形变化设计一副图案最好起个名称,并配上简单的设计说明 利用平移,旋转 轴对称 中心对称 设计图案,并说明含义. 我十个手指头都是簸箕,有什么说法? 菱形ABCD中,P是AB上的一动点(不与A,B重合),连接DP交对角线AC于点E,连接EB.若∠DAB=60°,试问点P运动到 干燥的I2与淀粉混合会变蓝吗?另外,是淀粉使I2变蓝还是I2使淀粉变蓝? 失火怎样自救 已知:如图,在菱形ABCD中,P是AB上一点,联接EB,求证:∠APD=∠EBC 求(上海高中)高一化学知识整理:整理硫、氮相关知识就是这个题目,只要求硫、氮的相关知识,其他的别给我找多谢 宿舍失火如何自救 已知如图 在菱形ABCD中,点E在对角线AC上,点F在BF的延长线上,BF=EB,EF与CD相交于G1)求证:EG.GF=CG.GD2)联接DF,如果EF垂直CD,那么FDC与ADC之间有怎么样的数量关系?证明结论(我不能画图)补充图片 怎样利用轴对称,平移,旋转,中心对称等等设计一个简单标志性图案? 氢气和氯气发生反应,氯化氢是什么产物?氧化产物还是还原产物 手纹:10个簸箕的男生和10个簸箕的女生我和我女朋友都是10个簸箕,而且她是白羊座,我是天枰座而且我们俩的观点好多都截然相反,谁在这方面比较给力的,我们在一起合适不?星座跟手纹的这 平移轴对称旋转都存在的好看的图形有嘛?因为我要画在纸上 亲们,谁知道一个人手上有十个簸箕,是什么寓意?
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘