zoukankan      html  css  js  c++  java
  • Android模拟小球自由落体2(重力感应并添加z轴)

    这次改进了昨天那个例子,添加了重力感应,并添加了z轴。这样算3D了吧(笑)。小球往屏幕里面落时会不断变小。改进了下绘图线程的控制,surfaceCreated时绘图线程启动,surfaceDestroyed时 绘图线程停止。还有极小概率会出现程序崩溃,不知道是不是不同线程同时读取KCList造成的,你们可以给KCList加个同步锁试试,概率太小了不好测试。

    下面是代码。

    package com.example.sft;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.RadialGradient;
    import android.graphics.Shader;
    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.View;
    
    public class TestSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
        
        private Paint cp;
        private List<KCircle> KCList;
        private Random r;
        private SensorManager sm;
        private MyThread mt;
    
        public TestSurfaceView(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
            getHolder().addCallback(this);
            cp=new Paint();
            cp.setColor(Color.BLACK);
            KCList=new ArrayList<KCircle>();
            r=new Random();
            sm=(SensorManager)context.getSystemService(context.SENSOR_SERVICE);
            Sensor sensor=sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            sm.registerListener(new SensorEventListener() {
                
                @Override
                public void onSensorChanged(SensorEvent event) {
                    // TODO Auto-generated method stub
                    KCircle.ax=-event.values[0]/16;
                    KCircle.ay=event.values[1]/16;
                    KCircle.az=-event.values[2]/16;
                    
                }
                
                @Override
                public void onAccuracyChanged(Sensor sensor, int accuracy) {
                    // TODO Auto-generated method stub
                    
                }
            }, sensor, SensorManager.SENSOR_DELAY_GAME);
        
            
        }
        
        
    
        @Override
        public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
            // TODO Auto-generated method stub
            
        }
    
        private int getRandomColor(){
            return r.nextInt()%0xff000000;
        }
        @Override
        public void surfaceCreated(SurfaceHolder arg0) {
            // TODO Auto-generated method stub
            if(mt==null||!mt.isRunning()){
                mt=new MyThread();
                mt.start();
            }
            
        }
        
    
        @Override
        public void surfaceDestroyed(SurfaceHolder arg0) {
            // TODO Auto-generated method stub
            mt.stopThread();
            
        }
        
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // TODO Auto-generated method stub
            
    
            KCList.add(new KCircle(getRandomColor(),(int)event.getX(),(int)event.getY()));
            return true;
        }
        
        class MyThread extends Thread{
            
            private boolean runningTag=true;
            @Override
            public void run() {
                // TODO Auto-generated method stub
                runningTag=true;
                while(runningTag){
                Canvas c=getHolder().lockCanvas();
                if(c!=null){
                c.drawPaint(cp);
                for(int i=0;i<KCList.size();i++){
                    
                    if(KCList.get(i).isShouldRemove()){
                        KCList.remove(i);
                    }else
                        KCList.get(i).drawAndMove(c);
                }
                
                getHolder().unlockCanvasAndPost(c);
                
                }
                
                
                try {
                    sleep(15);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                }
                
                Log.i("kagami", "stop");
                
            }
            
            
            public void stopThread(){
                runningTag=false;
            }
            
            public boolean isRunning(){
                return runningTag;
            }
        }
        
        
    }
    package com.example.sft;
    
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.RadialGradient;
    import android.graphics.Shader;
    import android.util.Log;
    
    
    public class KCircle {
        
        private int color;
        public int x;
        public int y;
        public int z;
        private Paint p;
        private int radius;
        float vx;
        float vy;
        float vz;
        static float ax=0;
        static float ay=0;
        static float az=0;
        
        
        public KCircle(int color){
            this.color=color;
            x=0;
            y=0;
            z=0;
            vx=0;
            vy=0;
            vz=0;
            radius=25;
            p=new Paint();
            p.setColor(color);
            RadialGradient rg=new RadialGradient(x+10, y-10, radius,color+(0xffffffff-color)/2, color, Shader.TileMode.CLAMP);
            
            p.setShader(rg);
            p.setAntiAlias(true);
        }
        
        public KCircle(int colcr,int x,int y){
            this(colcr);
            this.x=x;
            this.y=y;
        }
        
        public void drawAndMove(Canvas c){
            
            draw(c);
            x+=vx;
            y+=vy;
            z+=vz;
            vy+=ay;
            vx+=ax;
            vz+=az;
        }
        
        public void moveTo(int x,int y){
            this.x=x;
            this.y=y;
        }
        
        public void draw(Canvas c){
            RadialGradient rg=new RadialGradient(x+(25+z/100)/2, y-(25+z/100)/2, 25+z/100,0xffdddddd, color, Shader.TileMode.CLAMP);
            p.setShader(rg);
            c.drawCircle(x, y, 25+z/100, p);
    
        }
        
        public boolean isShouldRemove(){
            if(x<-1000||x>1000||y>1000||y<-1000||(25+z/100)<=0||(25+z/100)>150)
                return true;
            else
                return false;
        }
        
    
    }

    上面的图片效果和真实效果有些不同。。。  可能是DDMS的图片抓取机制的问题  看起来有断层,实际是没有的。

  • 相关阅读:
    【完结】php+MySQL实战案例【九】总结及源码分享
    php+MySQL实战案例【八】用户注册
    php+MySQL实战案例【七】数据编辑、删除
    php+MySQL实战案例【六】数据分页查询
    php+MySQL实战案例【五】新增用户
    php+MySQL实战案例【四】管理员登录
    php+MySQL实战案例【三】数据表设计
    php+MySQL实战案例【二】php数据库辅助类
    5700清空所有配置的方法
    华为设备默认console密码
  • 原文地址:https://www.cnblogs.com/kagami/p/3011882.html
Copyright © 2011-2022 走看看